Send patches - preferably formatted by git format-patch - to patches at archlinux32 dot org.
summaryrefslogtreecommitdiff
path: root/setup
diff options
context:
space:
mode:
Diffstat (limited to 'setup')
-rw-r--r--setup/cleanupaftersetup.php7
-rw-r--r--setup/composerit.php68
-rwxr-xr-xsetup/composerit.pl24
-rw-r--r--setup/composerit2.php78
-rwxr-xr-xsetup/composerit2.pl29
-rw-r--r--setup/composertest.php68
-rw-r--r--setup/exportdb.php27
-rw-r--r--setup/images/exclamation.pngbin0 -> 1917 bytes
-rw-r--r--setup/images/title.pngbin0 -> 13303 bytes
-rw-r--r--setup/index.php1226
-rw-r--r--setup/lang/de.php22
-rw-r--r--setup/lang/en.php101
-rw-r--r--setup/lang/es.php100
-rw-r--r--setup/lang/fr.php14
-rw-r--r--setup/lang/it.php100
-rw-r--r--setup/lang/zh_cn.php46
-rw-r--r--setup/styles/setup.css177
-rw-r--r--setup/styles/theme.css994
-rw-r--r--setup/templates/administration.tpl79
-rw-r--r--setup/templates/complete_install.tpl50
-rw-r--r--setup/templates/database.tpl47
-rw-r--r--setup/templates/pre_install.tpl124
-rw-r--r--setup/templates/structure.tpl56
-rw-r--r--setup/templates/upgrade.tpl76
-rw-r--r--setup/upgrade.php643
-rw-r--r--setup/upgrade/0.9.9.2/flyspray-install.xml1049
-rw-r--r--setup/upgrade/0.9.9.2/lowercase_emails.php6
-rw-r--r--setup/upgrade/0.9.9.2/update_users.xml70
-rw-r--r--setup/upgrade/0.9.9.2/upgrade.info34
-rw-r--r--setup/upgrade/0.9.9.4/flyspray-install.xml1055
-rw-r--r--setup/upgrade/0.9.9.4/upgrade.info32
-rw-r--r--setup/upgrade/0.9.9.4/upgrade.xml199
-rw-r--r--setup/upgrade/0.9.9.5/flyspray-install.xml1058
-rw-r--r--setup/upgrade/0.9.9.5/upgrade.info34
-rw-r--r--setup/upgrade/0.9.9.5/upgrade.xml41
-rw-r--r--setup/upgrade/0.9.9.7/flyspray-install.xml1059
-rw-r--r--setup/upgrade/0.9.9.7/upgrade.info35
-rw-r--r--setup/upgrade/0.9.9/add_data.php34
-rw-r--r--setup/upgrade/0.9.9/add_duplicates.php41
-rw-r--r--setup/upgrade/0.9.9/add_searches.php22
-rw-r--r--setup/upgrade/0.9.9/clean_unique.php67
-rw-r--r--setup/upgrade/0.9.9/convert_categories.php43
-rw-r--r--setup/upgrade/0.9.9/convert_private.php26
-rw-r--r--setup/upgrade/0.9.9/flyspray-begin.xml748
-rw-r--r--setup/upgrade/0.9.9/flyspray-final.xml976
-rw-r--r--setup/upgrade/0.9.9/flyspray-install.xml1044
-rw-r--r--setup/upgrade/0.9.9/rename_columns.php14
-rw-r--r--setup/upgrade/0.9.9/upgrade.info44
-rw-r--r--setup/upgrade/0.9.9/upgrade_assignments.php31
-rw-r--r--setup/upgrade/1.0/datadict-postgres.inc.php606
-rw-r--r--setup/upgrade/1.0/flyspray-install.xml1373
-rw-r--r--setup/upgrade/1.0/upgrade.info70
-rw-r--r--setup/upgrade/1.0/upgrade.xml902
-rw-r--r--setup/upgrade/1.0/varchartotext.php17
54 files changed, 14886 insertions, 0 deletions
diff --git a/setup/cleanupaftersetup.php b/setup/cleanupaftersetup.php
new file mode 100644
index 0000000..a62ed7d
--- /dev/null
+++ b/setup/cleanupaftersetup.php
@@ -0,0 +1,7 @@
+<?php
+chdir('..');
+$hide='_'.md5(rand().time()).'_setup';
+rename('setup', $hide); # Hide the setup dir with a random name, not deleting it. Just in case to have the complete software together or something got wrong.
+chmod($hide, 0400); # make it extra unaccessible (directory x bit) just in case the dir lands on search engines index..
+echo '<a href="../">You can now use Flyspray.</a>';
+?>
diff --git a/setup/composerit.php b/setup/composerit.php
new file mode 100644
index 0000000..75c2175
--- /dev/null
+++ b/setup/composerit.php
@@ -0,0 +1,68 @@
+<?php
+@set_time_limit(0);
+ini_set('memory_limit', '64M');
+
+define('IN_FS', 1);
+define('BASEDIR', dirname(__FILE__));
+define('APPLICATION_PATH', dirname(BASEDIR));
+define('OBJECTS_PATH', APPLICATION_PATH . '/includes');
+define('TEMPLATE_FOLDER', BASEDIR . '/templates/');
+
+require_once OBJECTS_PATH.'/i18n.inc.php';
+
+class user{var $infos=array();};
+class project{var $id=0;};
+$user = new user;
+$proj = new project;
+
+load_translations();
+
+# no caching to prevent old pages if user goes back and forth during install
+header("Expires: Tue, 03 Jul 2001 06:00:00 GMT");
+header("Cache-Control: no-store, no-cache, must-revalidate, max-age=0");
+header("Cache-Control: post-check=0, pre-check=0", false);
+header("Pragma: no-cache");
+?>
+
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset='utf-8'>
+ <title>Flyspray Install - Third Party Packages needed</title>
+ <link media="screen" href="../themes/CleanFS/theme.css" rel="stylesheet" type="text/css" />
+ </head>
+ <body style="padding:2em;"><img src="../flyspray.png" style="display:block;margin:auto;">
+ <h3>Step 1: Trying to download Composer</h3>
+<?php
+ if (ini_get('safe_mode') == 1) {
+ $composerfile = file_get_contents('https://getcomposer.org/installer');
+ file_put_contents('composerinstaller', $composerfile);
+ echo 'Download done'.'<br>';
+ $argv = array('--disable-tls'); # just for avoiding warnings
+ ?>
+ <h3>Step 2: Trying to load composerinstaller into the running php script</h3>
+ <p>Wait a few seconds until composerinstaller put his output under the button. Once the output looks good, try installing the dependencies using the button.</p>
+ <a href="composerit2.php" class="button" style="padding:1em;font-size:1em">Install dependencies</a>
+ <pre>
+ <?php
+ require 'composerinstaller';
+ # Ok, composerinstaller exits itself, so no more code needed here, but it looks more complete :-)
+ echo '</pre>';
+ } else {
+ $phpexe='php';
+ # TODO: autodetect the matching commandline php on the host matching the php version of the webserver
+ # Any idea? Using $_SERVER['PHP_PEAR_SYSCONF_DIR'] or $_SERVER['PHPRC'] for detecting can help a bit, but weak hints..
+ # This is just a temp hack for installing flyspray on xampp on Windows
+ if (getenv('OS') == 'Windows_NT' && isset($_SERVER['PHPRC']) && strstr($_SERVER['PHPRC'], 'xampp')) {
+ $phpexe=$_SERVER['PHPRC'].'\php.exe';
+ }
+ shell_exec($phpexe.' -r "readfile(\'https://getcomposer.org/installer\');" | '.$phpexe);
+ if (!is_readable('composer.phar')) {
+ die('Composer installer download failed! Please consider downloading vendors directly from Flyspray support website');
+ }
+ echo 'Successfully downloaded Composer.<br /><br />';
+ echo '<a href="composerit2.php" class="button" style="padding:1em;font-size:1em">Try to install dependencies</a>';
+ }
+?>
+</body>
+</html>
diff --git a/setup/composerit.pl b/setup/composerit.pl
new file mode 100755
index 0000000..6363430
--- /dev/null
+++ b/setup/composerit.pl
@@ -0,0 +1,24 @@
+#!/usr/bin/perl
+use CGI;
+
+$cgi=new CGI;
+print $cgi->header();
+print '<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Flyspray Install - curl -sS https://getcomposer.org/installer | php</title>
+<link media="screen" href="../themes/CleanFS/theme.css" rel="stylesheet" type="text/css" />
+</head>
+<body style="padding:2em;"><img src="../flyspray.png" style="display:block;margin:auto;">
+';
+print '<h3>Trying to load composer stuff</h3><pre>&gt; curl -sS https://getcomposer.org/installer | php</pre>';
+chdir('../');
+@step1= `curl -sS https://getcomposer.org/installer | php`;
+print '<h3>Step 1 result</h3><br/><pre>';
+foreach (@step1) {
+ print;
+}
+print '</pre>';
+
+print '<a class="button" style="text-align:center;margin:auto;display:block;max-width:300px;font-size:2em;" href="composerit2.pl">Next Step</a>';
diff --git a/setup/composerit2.php b/setup/composerit2.php
new file mode 100644
index 0000000..09aade9
--- /dev/null
+++ b/setup/composerit2.php
@@ -0,0 +1,78 @@
+<?php
+@set_time_limit(0);
+ini_set('memory_limit', '64M');
+
+define('IN_FS', 1);
+define('BASEDIR', dirname(__FILE__));
+define('APPLICATION_PATH', dirname(BASEDIR));
+define('OBJECTS_PATH', APPLICATION_PATH . '/includes');
+define('TEMPLATE_FOLDER', BASEDIR . '/templates/');
+
+require_once OBJECTS_PATH.'/i18n.inc.php';
+class user{var $infos=array();};
+class project{var $id=0;};
+$user = new user;
+$proj = new project;
+load_translations();
+
+# no caching to prevent old pages if user goes back and forth during install
+header("Expires: Tue, 03 Jul 2001 06:00:00 GMT");
+header("Cache-Control: no-store, no-cache, must-revalidate, max-age=0");
+header("Cache-Control: post-check=0, pre-check=0", false);
+header("Pragma: no-cache");
+
+?>
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset='utf-8'>
+ <title>Flyspray Install - Third Party Packages needed - Step 3</title>
+ <link media="screen" href="../themes/CleanFS/theme.css" rel="stylesheet" type="text/css" />
+ </head>
+ <body style="padding:2em;"><img src="../flyspray.png" style="display:block;margin:auto;">
+ <?php
+ if (ini_get('safe_mode') == 1) {
+ echo '
+ <h3>PHP safe_mode is enabled. We currently don\'t know how to run the "php composer.phar install" from php web frontend under this circumstances.</h3>
+ <h3>But lets test if we can workaround it with Perl:</h3>
+ <a href="composerit2.pl" class="button">Test using Perl: composerit2.pl</a>';
+ } else {
+ echo '<h3>Step 3: Trying to install dependencies</h3>';
+ # $argv=('install');
+ # chdir('..');
+ # echo '<pre>';
+ # require 'composer.phar';
+ # echo '</pre>';
+
+ # without chdir('..');
+ $phpexe='php';
+ # TODO: autodetect the matching commandline php on the host matching the php version of the webserver
+ # Any idea? Using $_SERVER['PHP_PEAR_SYSCONF_DIR'] or $_SERVER['PHPRC'] for detecting can help a bit, but weak hints..
+ # This is just a temp hack for installing flyspray on xampp on Windows
+ if (getenv('OS') == 'Windows_NT' && isset($_SERVER['PHPRC']) && strstr($_SERVER['PHPRC'], 'xampp')) {
+ $phpexe=$_SERVER['PHPRC'].'\php.exe';
+ }
+ $cmd2 = $phpexe.' composer.phar --working-dir=.. install';
+
+ # with chdir('..');
+ #$cmd2 = 'php composer.phar install';
+
+ echo $cmd2.'<br/><br/>';
+ shell_exec($cmd2);
+ echo '<strong>Done</strong>';
+
+ echo '<h3>Step 4: Checking and cleaning:</h3>';
+ if (is_readable('../vendor/autoload.php')) {
+ echo 'Composer installation ok<br />';
+ } else {
+ echo 'Composer installation failed<br />';
+ }
+ if (is_file('composer.phar')) {
+ unlink('composer.phar');
+ }
+ echo 'Cleanup made<br /><br />';
+ echo '<a href="./index.php" class="button">Go back</a>';
+ }
+ ?>
+ </body>
+</html>
diff --git a/setup/composerit2.pl b/setup/composerit2.pl
new file mode 100755
index 0000000..04bd81b
--- /dev/null
+++ b/setup/composerit2.pl
@@ -0,0 +1,29 @@
+#!/usr/bin/perl
+use CGI;
+
+$cgi=new CGI;
+print $cgi->header(
+ -expires => 'Sat, 26 Jul 1997 05:00:00 GMT',
+ -Pragma => 'no-cache',
+ -Cache_Control => join(', ', qw(private no-cache no-store must-revalidate max-age=0 pre-check=0 post-check=0)),
+);
+print '<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Flyspray Install - php composer.phar install</title>
+<link media="screen" href="../themes/CleanFS/theme.css" rel="stylesheet" type="text/css" />
+</head>
+<body style="padding:2em;"><img src="../flyspray.png" style="display:block;margin:auto;">
+';
+
+print '<h3>Trying to install packages</h3>';
+print '<a class="button" style="text-align:center;margin:auto;min-width:300px;" href="index.php">Go to setup page</a>';
+#chdir('..');
+@step2= `export COMPOSER_HOME=. ; php composer.phar --working-dir=.. install 2>&1`;
+print '<pre>&gt; php composer.phar install</pre>';
+print '<pre>';
+foreach (@step2) {
+ print;
+}
+print '</pre>';
diff --git a/setup/composertest.php b/setup/composertest.php
new file mode 100644
index 0000000..b8a5663
--- /dev/null
+++ b/setup/composertest.php
@@ -0,0 +1,68 @@
+<?php
+
+@set_time_limit(0);
+ini_set('memory_limit', '64M');
+
+define('IN_FS', 1);
+define('BASEDIR', dirname(__FILE__));
+define('APPLICATION_PATH', dirname(BASEDIR));
+define('OBJECTS_PATH', APPLICATION_PATH . '/includes');
+define('TEMPLATE_FOLDER', BASEDIR . '/templates/');
+
+require_once OBJECTS_PATH.'/i18n.inc.php';
+class user{var $infos=array();}; class project{var $id=0;};
+$user=new user; $proj=new project;
+load_translations();
+
+# no caching to prevent old pages if user goes back and forth during install
+header("Expires: Tue, 03 Jul 2001 06:00:00 GMT");
+header("Cache-Control: no-store, no-cache, must-revalidate, max-age=0");
+header("Cache-Control: post-check=0, pre-check=0", false);
+header("Pragma: no-cache");
+
+# Step 1 and 2 of composer install now working also with SAFE_MODE enabled in php5.3.*
+#if(ini_get('safe_mode') == 1){
+# $composerit = 'composerit.pl'; // try it with perl scripts
+#}else{
+ $composerit = 'composerit.php'; // try it with php
+#}
+?>
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset='utf-8'>
+ <title>Flyspray Install - Third Party Packages needed</title>
+ <link media="screen" href="../themes/CleanFS/theme.css" rel="stylesheet" type="text/css" />
+</head>
+<body style="padding:2em;"><img src="../flyspray.png" style="display:block;margin:auto;">
+ <h2>It seems you try to install a development version of Flyspray.</h2>
+ <h2><?php echo L('needcomposer'); ?></h2>
+ <a href="<?php echo $composerit; ?>" class="button" style="margin:auto;max-width:300px;text-align:center;display:block;font-size:2em;"><?php echo L('installcomposer'); ?></a>
+ <p style="margin-top:50px;">
+ In case the above solution doesn't work for you, use ssh to login to your server, move to the root directory of your unpacked flyspray sources and execute this:
+ </p>
+ <pre>
+ curl -sS https://getcomposer.org/installer | php
+ php composer.phar install
+ </pre>
+
+<div class="error">
+<h4>Shared Hostings</h4>
+<p>If you are on a shared hosting, there are probably different php versions available. The hosting companies name them often like <b>php5.4</b>, <b>php5.5-cli</b> or <b>php-cgi-7.0</b>. Choose the best matching php-version for your Hosting (should ideally match that of what the webserver uses). To see available php versions on the commandline type</p>
+<pre><strong>php</strong> <kbd class="key">tab</kbd> <kbd class="key">tab</kbd></pre>
+<p><kbd>tab</kbd> <kbd>tab</kbd> is autocompletion on bash, so it shows all executable that start with <strong>php</strong>.</p>
+<p>Lets say the webserver uses PHP 5.6 by default, than a <b>php5.6</b> you found on the commandline is a good choice:</p>
+<pre>curl -sS https://getcomposer.org/installer | php5.6
+php5.6 composer.phar install
+</pre>
+</div>
+
+ <p>Or take an official release, which contains all needed external packages bundled.</p>
+ <h2>README.md</h2>
+ <div id="content">
+ <pre>
+ <?php echo file_get_contents('../README.md'); ?>
+ </pre>
+ </div>
+</body>
+</html>
diff --git a/setup/exportdb.php b/setup/exportdb.php
new file mode 100644
index 0000000..fd714a3
--- /dev/null
+++ b/setup/exportdb.php
@@ -0,0 +1,27 @@
+<?php
+
+error_reporting(E_ALL);
+
+die('Enable me by commenting this out by editing '.basename(__FILE__).' at line '.__LINE__);
+
+require_once '../vendor/adodb/adodb-php/adodb.inc.php';
+require_once '../vendor/adodb/adodb-php/adodb-xmlschema03.inc.php';
+
+$conf = @parse_ini_file('../flyspray.conf.php', true) or die('Cannot open config file.');
+
+/* Start by creating a normal ADODB connection. */
+$db = ADONewConnection($conf['database']['dbtype']);
+$db->Connect( $conf['database']['dbhost'], $conf['database']['dbuser'],
+ $conf['database']['dbpass'], $conf['database']['dbname']) or die('Cannot connect to DB.');
+$db->debug= true;
+
+/* Use the database connection to create a new adoSchema object. */
+$schema = new adoSchema($db);
+
+$withdata=false;
+$stripprefix=true;
+$data = $schema->ExtractSchema( $withdata, ' ', $conf['database']['dbprefix'], $stripprefix);
+
+file_put_contents('flyspray-schema.xml', $data);
+
+?>
diff --git a/setup/images/exclamation.png b/setup/images/exclamation.png
new file mode 100644
index 0000000..3e788f5
--- /dev/null
+++ b/setup/images/exclamation.png
Binary files differ
diff --git a/setup/images/title.png b/setup/images/title.png
new file mode 100644
index 0000000..9f615da
--- /dev/null
+++ b/setup/images/title.png
Binary files differ
diff --git a/setup/index.php b/setup/index.php
new file mode 100644
index 0000000..f55e748
--- /dev/null
+++ b/setup/index.php
@@ -0,0 +1,1226 @@
+<?php
+// +----------------------------------------------------------------------
+// | Installer - there is still a lot to clean up, but it works
+// +----------------------------------------------------------------------
+// | Copyright (C) 2005 by Jeffery Fernandez <developer@jefferyfernandez.id.au>
+// | Copyright (C) 2006-2007 by Cristian Rodriguez <judas.iscariote@flyspray.org> and Florian Schmitz <floele@gmail.com>
+// +----------------------------------------------------------------------
+
+@set_time_limit(0);
+ini_set('memory_limit', '64M');
+
+define('IN_FS', 1 );
+define('APPLICATION_NAME', 'Flyspray');
+define('BASEDIR', dirname(__FILE__));
+define('APPLICATION_PATH', dirname(BASEDIR));
+define('OBJECTS_PATH', APPLICATION_PATH . '/includes');
+define('TEMPLATE_FOLDER', BASEDIR . '/templates/');
+
+require_once OBJECTS_PATH.'/fix.inc.php';
+require_once OBJECTS_PATH.'/class.gpc.php';
+require_once OBJECTS_PATH.'/class.flyspray.php';
+require_once OBJECTS_PATH.'/i18n.inc.php';
+require_once OBJECTS_PATH.'/class.tpl.php';
+
+// Load translations
+load_translations();
+
+# must be sure no-cache before any possible redirect, we maybe come back later here after composer install stuff.
+header("Expires: Tue, 03 Jul 2001 06:00:00 GMT");
+header("Cache-Control: no-store, no-cache, must-revalidate, max-age=0");
+header("Cache-Control: post-check=0, pre-check=0", false);
+header("Pragma: no-cache");
+
+if (is_readable(APPLICATION_PATH . '/vendor/autoload.php')){
+ // Use composer autoloader
+ require APPLICATION_PATH . '/vendor/autoload.php';
+} else{
+ Flyspray::redirect('composertest.php');
+ exit;
+}
+
+// no transparent session id improperly configured servers
+ini_set('session.use_trans_sid', 0);
+session_start();
+
+if (is_readable('../flyspray.conf.php') && count(parse_ini_file('../flyspray.conf.php')) > 0){
+ die('<div style="text-align:center;padding:20px;font-family:sans-serif;font-size:16px;">
+Flyspray already installed. Use the <a href="upgrade.php"
+style="
+margin:2em;
+background-color: white;
+border: 1px solid #bbb;
+border-radius: 4px;
+box-shadow: 0 1px 1px #ddd;
+color: #565656;
+cursor: pointer;
+display: inline-block;
+font-family: sans-serif;
+font-size: 100%;
+font-weight: bold;
+line-height: 130%;
+padding: 8px 13px 8px 10px;
+text-decoration: none;
+">Upgrader</a> to upgrade your Flyspray,
+or delete flyspray.conf.php to run setup. You can *not* use the setup on an existing database.</div>');
+}
+
+$conf['general']['syntax_plugin'] = '';
+
+// ---------------------------------------------------------------------
+// Application Web locations
+// ---------------------------------------------------------------------
+define('APPLICATION_SETUP_INDEX', Flyspray::absoluteURI());
+
+class Setup extends Flyspray
+{
+ public $mPhpRequired;
+ public $mSupportedDatabases;
+ public $mAvailableDatabases;
+
+ public $mProceed;
+ public $mPhpVersionStatus;
+ public $mDatabaseStatus;
+ public $xmlStatus;
+ public $mConfigText;
+ public $mHtaccessText;
+ public $mWriteStatus;
+
+ public $mDbConnection;
+ public $mProductName;
+
+ /**
+ * @var string To store the data filter type
+ */
+ public $mDataFilter;
+
+ /**
+ * @var array To store the type of database setup (install or Upgrade).
+ */
+
+ public $mAttachmentsTable;
+ public $mCommentsTable;
+
+ public $mServerSoftware;
+ public $mMinPasswordLength;
+ public $mAdminUsername;
+ public $mAdminPassword;
+ /**
+ * @var object to store the adodb datadict object.
+ */
+ public $mDataDict;
+
+ public $mXmlSchema;
+
+ public function __construct()
+ {
+ // Look for ADOdb
+ $this->mAdodbPath = dirname(__DIR__) . '/vendor/adodb/adodb-php/adodb.inc.php';
+ $this->mProductName = 'Flyspray';
+ $this->mMinPasswordLength = 8;
+
+ // Initialise flag for proceeding to next step.
+ $this->mProceed = false;
+ $this->mPhpRequired = '5.4';
+ $this->xmlStatus = function_exists('xml_parser_create');
+ $this->sapiStatus = (php_sapi_name() != 'cgi');
+
+ // If the database is supported in Flyspray, the function to check in PHP.
+ $this->mSupportedDatabases = array(
+ 'MySQLi' => array(true,'mysqli_connect','mysqli'),
+ 'MySQL' => array(true, 'mysql_connect', 'mysql'),
+ 'Postgres' => array(true, 'pg_connect', 'pgsql'),
+ );
+ $this->mAvailableDatabases = array();
+
+ // Process the page actions
+ $this->processActions();
+ }
+
+ /**
+ * Function to check the permission of the config file
+ * @param void
+ * @return string An html formatted boolean answer
+ */
+ public function checkWriteability($path)
+ {
+ // Get the full path to the file
+ $file = APPLICATION_PATH .'/' . $path;
+
+ // In case it is flyspray.conf.php, the file does not exist
+ // so we can't tell that it is writeable. So we attempt to create an empty one
+ if ($path == 'flyspray.conf.php') {
+ $fp = @fopen($file, 'wb');
+ @fclose($fp);
+ // Let's try at least...
+ #@chmod($file, 0666);
+ @chmod($file, 0644); # looks a bit better than worldwritable
+ }
+ if(is_dir($path)){
+ # for cache and attachement directories x-bit needed
+ @chmod($file, 0755);
+ }
+ $this->mWriteStatus[$path] = $this->IsWriteable($file);
+
+ // Return an html formated writeable/un-writeable string
+ return $this->returnStatus($this->mWriteStatus[$path], $type = 'writeable');
+ }
+
+ /**
+ * Function to check the availability of the Database support
+ * @param void
+ * @return void
+ */
+ public function checkDatabaseSupport()
+ {
+ $status = array();
+
+ foreach ($this->mSupportedDatabases as $which => $database)
+ {
+ // Checking if the database has libraries built into PHP. Returns true/false
+ $this->mAvailableDatabases[$which]['status'] = function_exists($database[1]);
+
+ // If the Application(Flyspray) supports the available database supported in PHP
+ $this->mAvailableDatabases[$which]['supported'] = ($database[0] === $this->mAvailableDatabases[$which]['status'])
+ ? $this->mAvailableDatabases[$which]['status']
+ : false;
+
+ // Just transferring the value for ease of veryfying Database support.
+ $status[] = $this->mAvailableDatabases[$which]['supported'];
+
+ // Generating the output to be displayed
+ $this->mAvailableDatabases[$which]['status_output'] =
+ $this->returnStatus($this->mAvailableDatabases[$which]['status'], $type = 'available');
+ }
+
+ // Check if any one database support exists.
+ // Update the status of database availability
+ $this->mDatabaseStatus = in_array('1', $status);
+ }
+
+
+ /**
+ * CheckPreStatus
+ * we proceed or not ?
+ * @access public
+ * @return bool
+ */
+ public function checkPreStatus()
+ {
+ $this->mProceed = ($this->mDatabaseStatus && $this->mPhpVersionStatus && $this->xmlStatus);
+
+ return $this->mProceed;
+ }
+
+
+ /**
+ * Function to check the version of PHP available compared to the
+ * Applications requirements
+ * @param void
+ * @return string An html formatted boolean answer
+ */
+ public function checkPhpCompatibility()
+ {
+ // Check the PHP version.
+ $this->mPhpVersionStatus = version_compare(PHP_VERSION, $this->mPhpRequired, '>=');
+
+ // Return an html formated Yes/No string
+ return $this->returnStatus($this->mPhpVersionStatus, $type = 'yes');
+ }
+
+ /**
+ * Function to check the posted data from forms.
+ * @param array $expectedFields Array of field names which needs processing
+ * If the array of filed names don't exist in the Posted data, then this function
+ * will accumulate error messages in the $_SESSION[PASS_PHRASE]['page_message'] array.
+ * return boolean/array $data will be returned if successful
+ */
+ public function checkPostedData($expectedFields, $pageHeading)
+ {
+ if(!is_array($expectedFields)){
+ $expectedFields = array();
+ }
+
+ // Grab the posted data and trim it.
+ $data = array_filter($_POST, array(&$this, "trimArgs"));
+
+
+ // Loop through the required values and check data
+ foreach($expectedFields as $key => $value)
+ {
+
+ // If the data is Required and is empty or not set
+ if (!isset($data[$key]) || empty($data[$key]))
+ {
+ if ($expectedFields[$key][2] == true)
+ {
+ // accumulate error messages
+ $_SESSION['page_message'][] = "<strong>{$expectedFields[$key][0]}</strong> is required";
+ }
+ }
+ // Check for variable types
+ elseif (!$this->verifyVariableTypes($expectedFields[$key][1], $data[$key]))
+ {
+ $_SESSION['page_message'][] = "<strong>{$expectedFields[$key][0]}</strong> has to be a {$expectedFields[$key][1]}";
+ }
+ }
+
+ // If there were messages, return false
+ if (isset($_SESSION['page_message']))
+ {
+ $_SESSION['page_heading'] = $pageHeading;
+ return false;
+ }
+ else
+ {
+ return $data;
+ }
+ }
+
+ public function displayAdministration()
+ {
+ // Trim the empty values in the $_POST array
+ $data = array_filter($_POST, array($this, "trimArgs"));
+
+ $templates =
+ array(
+ 'admin_body' => array(
+ 'path' => TEMPLATE_FOLDER,
+ 'template' => 'administration.tpl',
+ 'vars' => array(
+ 'product_name' => $this->mProductName,
+ 'message' => $this->getPageMessage(),
+ 'admin_email' => $this->getParamValue($data, 'admin_email', ''),
+ 'pass_phrase' => $this->getParamValue($data, 'pass_phrase', ''),
+ 'admin_username' => $this->getParamValue($data, 'admin_username', ''),
+ 'admin_realname' => $this->getParamValue($data, 'admin_realname', ''),
+ 'admin_xmpp' => $this->getParamValue($data, 'admin_xmpp', ''),
+ 'admin_password' => $this->getParamValue($data, 'admin_password', substr(md5(mt_rand()), 0, $this->mMinPasswordLength)),
+ 'db_type' => $this->getParamValue($data, 'db_type', ''),
+ 'db_hostname' => $this->getParamValue($data, 'db_hostname', ''),
+ 'db_username' => $this->getParamValue($data, 'db_username', ''),
+ 'db_password' => $this->getParamValue($data, 'db_password', ''),
+ 'db_name' => $this->getParamValue($data, 'db_name', ''),
+ 'db_prefix' => $this->getParamValue($data, 'db_prefix', ''),
+ 'daemonise' => $this->getReminderDaemonSelection($this->getParamValue($data, 'reminder_daemon', '0')),
+ ),
+ ),
+
+ 'structure' => array(
+ 'path' => TEMPLATE_FOLDER,
+ 'template' => 'structure.tpl',
+ 'vars' => array(
+ 'title' => 'Administration setup for',
+ 'headers' => '',
+ 'index' => APPLICATION_SETUP_INDEX,
+ 'version' => $this->version,
+ ),
+ 'block' => array('body' => 'admin_body')
+ )
+ );
+
+ // Output the final template.
+ $this->outputPage($templates);
+ }
+
+
+ public function displayCompletion()
+ {
+ // Trim the empty values in the $_POST array
+ $data = array_filter($_POST, array($this, "trimArgs"));
+
+ $templates =
+ array(
+ 'complete_body' => array(
+ 'path' => TEMPLATE_FOLDER,
+ 'template' => 'complete_install.tpl',
+ 'vars' => array(
+ 'product_name' => $this->mProductName,
+ 'message' => $this->getPageMessage(),
+ 'config_writeable' => $this->mWriteStatus['flyspray.conf.php'],
+ 'config_text' => $this->mConfigText,
+ 'admin_username' => $this->mAdminUsername,
+ 'admin_password' => $this->mAdminPassword,
+ 'site_index' => dirname($_SERVER['REQUEST_URI']) . '/../',
+ 'complete_action' => 'index.php',
+ 'daemonise' => true,
+ ),
+ ),
+
+ 'structure' => array(
+ 'path' => TEMPLATE_FOLDER,
+ 'template' => 'structure.tpl',
+ 'vars' => array(
+ 'title' => 'Setup confirmation for',
+ 'headers' => '',
+ 'index' => APPLICATION_SETUP_INDEX,
+ 'version' => $this->version,
+ ),
+ 'block' => array('body' => 'complete_body')
+ )
+ );
+
+ // Output the final template.
+ $this->outputPage($templates);
+ }
+
+ public function displayDatabaseSetup()
+ {
+
+ // Trim the empty values in the $_POST array
+ $data = array_filter($_POST, array($this, "trimArgs"));
+ $this->checkDatabaseSupport();
+
+ // Make sure that the user can't choose a DB which is not supported
+ foreach ($this->mSupportedDatabases as $db => $arr) {
+ if (!$this->mAvailableDatabases[$db]['supported']) {
+ unset($this->mSupportedDatabases[$db]);
+ }
+ }
+
+ $templates =
+ array(
+ 'database_body' => array(
+ 'path' => TEMPLATE_FOLDER,
+ 'template' => 'database.tpl',
+ 'vars' => array(
+ 'product_name' => $this->mProductName,
+ 'message' => $this->getPageMessage(),
+ 'databases' => $this->mSupportedDatabases,
+ 'db_type' => $this->getParamValue($data, 'db_type', ''),
+ 'db_hostname' => $this->getParamValue($data, 'db_hostname', 'localhost'),
+ 'db_username' => $this->getParamValue($data, 'db_username', ''),
+ 'db_password' => $this->getParamValue($data, 'db_password', ''),
+ 'db_name' => $this->getParamValue($data, 'db_name', ''),
+ 'db_prefix' => $this->getParamValue($data, 'db_prefix', 'flyspray_'),
+ 'version' => $this->version,
+ ),
+ ),
+ 'structure' => array(
+ 'path' => TEMPLATE_FOLDER,
+ 'template' => 'structure.tpl',
+ 'vars' => array(
+ 'title' => 'Database setup for',
+ 'headers' => '',
+ 'index' => APPLICATION_SETUP_INDEX,
+ 'version' => $this->version,
+ ),
+ 'block' => array('body' => 'database_body')
+ )
+ );
+
+ // Output the final template.
+ $this->outputPage($templates);
+ }
+
+
+ public function displayPreInstall()
+ {
+ // Check the Database support on the server.
+ $this->checkDatabaseSupport();
+
+ $templates =
+ array(
+ 'index_body' => array(
+ 'path' => TEMPLATE_FOLDER,
+ 'template' => 'pre_install.tpl',
+ 'vars' => array(
+ 'product_name' => $this->mProductName,
+ 'required_php' => $this->mPhpRequired,
+ 'php_output' => $this->checkPhpCompatibility(),
+ 'database_output' => $this->getDatabaseOutput(),
+ 'config_output' => $this->checkWriteability('flyspray.conf.php'),
+ 'cache_output' => $this->checkWriteability('cache'),
+ 'att_output' => $this->checkWriteability('attachments'),
+ 'ava_output' => $this->checkWriteability('avatars'),
+ 'config_status' => $this->mWriteStatus['flyspray.conf.php'],
+ 'xmlStatus' => $this->xmlStatus,
+ 'sapiStatus' => $this->sapiStatus,
+ 'php_settings' => $this->getPhpSettings(),
+ 'status' => $this->checkPreStatus(),
+ 'message' => $this->getPageMessage(),
+ ),
+ ),
+
+ 'structure' => array(
+ 'path' => TEMPLATE_FOLDER,
+ 'template' => 'structure.tpl',
+ 'vars' => array(
+ 'title' => 'Pre-Installation Check for',
+ 'headers' => '',
+ 'index' => APPLICATION_SETUP_INDEX,
+ 'version' => $this->version,
+ ),
+ 'block' => array('body' => 'index_body')
+ )
+ );
+
+ // Output the final template.
+ $this->outputPage($templates);
+ }
+
+ public function getDatabaseOutput()
+ {
+ $output = '';
+ // Loop through the supported databases array
+ foreach ($this->mSupportedDatabases as $which => $database)
+ {
+ $output .= "
+ <tr>
+ <td> - $which support</td>
+ <td align=\"left\"><strong>{$this->mAvailableDatabases[$which]['status_output']}</strong></td>
+ <td align=\"center\"><strong>". $this->returnStatus($this->mAvailableDatabases[$which]['supported'], $type = 'support') . "</strong></td>
+ </tr>";
+
+ }
+ // Return the html formatted results
+ return $output;
+ }
+
+
+ /**
+ * Function to get the php ini config values
+ * @param string $option The ini setting name to check the status for
+ * @return string The status of the setting either "On" or "OFF"
+ */
+ public function getIniSetting($option)
+ {
+ return (ini_get($option) == '1' ? L('on') : L('off'));
+ }
+
+ /**
+ * Function to get the error messages and generate an error output for the template
+ * @string $heading The value for the Error message heading
+ * The error message is stored in the $_SESSION Global array
+ * $_SESSION[PASS_PHRASE]['page_message']. If there is no value in
+ * this array, then there will be no error message outputed.
+ * @return string $message The message which needs outputting
+ */
+ public function getPageMessage()
+ {
+ // If there is an error
+ if (isset($_SESSION['page_message']) || isset($_SESSION['page_heading']))
+ {
+ $message = '';
+ if (isset($_SESSION['page_heading'])) {
+ $message = '<h1 class="error">' . $_SESSION['page_heading'] . '</h1>';
+ }
+
+ if (isset($_SESSION['page_message'])) {
+ // Get an html formated list
+ $message .= '<div class="box"><div class="shade">' . $this->outputHtmlList($_SESSION['page_message'],'ul') . '</div></div>';
+ }
+
+
+ // Destroy the session value
+ unset($_SESSION['page_heading']);
+ unset($_SESSION['page_message']);
+
+ return $message;
+ }
+ else
+ {
+ return '';
+ }
+ }
+
+
+ /**
+ * Utility function to return a value from a named array or a specified default
+ * @param array &$arr The array to get the values from
+ * @param string $name The name of the key to check the value for
+ * @param string $default The default value if the value is not set with the array
+ * @return string $value The value to be returned
+ */
+ public function getParamValue(&$arr, $name, $default=null )
+ {
+ $value = isset($arr[$name]) ? $arr[$name] : $default;
+ return $value;
+ }
+
+ /**
+ * Function to get a listing of recommended and actual settings
+ * for php.
+ * @param void
+ * @return string $output HTML formatted string.
+ */
+ public function getPhpSettings()
+ {
+ // Array of the setting name, php ini name and the recommended value
+ $test_settings =
+ array(
+ //array ('Safe Mode','safe_mode', L('off')), # removed since PHP5.4
+ array ('File Uploads','file_uploads', L('on')),
+ //array ('Magic Quotes GPC','magic_quotes_gpc', L('off')), # removed since PHP5.4
+ //array ('Register Globals','register_globals', L('off')), # removed since PHP5.4
+ //array ('Output Buffering','output_buffering', L('off')),
+ );
+
+ if (substr(php_sapi_name(), 0, 3) == 'cgi') {
+ $test_settings[] = array('CGI fix pathinfo','cgi.fix_pathinfo', L('on'));
+ }
+
+ $output = '';
+
+ foreach ($test_settings as $recommended)
+ {
+ $actual_setting = $this->getIniSetting($recommended[1]);
+
+ $result = ($actual_setting == $recommended[2] )
+ ? '<span class="green"><strong>' . $recommended[2] . '</strong></span>'
+ : '<span class="red"><strong>' . $actual_setting . '</strong></span>';
+
+ $output .=
+ "
+ <tr>
+ <td>{$recommended[0]}</td><td align=\"center\"><strong>{$recommended[2]}</strong></td><td align=\"center\">{$result}</td>
+ </tr>
+ ";
+ }
+ return $output;
+ }
+
+ public function getReminderDaemonSelection($value)
+ {
+ $selection = '<input type="radio" id="schedyes" name="reminder_daemon" value="1"'.($value==1 ? ' checked="checked"':'').' /> <label for="schedyes">'.L('enable').'</label>';
+ $selection .= '<input type="radio" id="schedno" name="reminder_daemon" value="0"'.($value==0 ? ' checked="checked"':'').' /> <label for="schedno">'.L('disable').'</label>';
+ return $selection;
+ }
+
+
+ /**
+ * Function to check if a particular folder/file is writeable.
+ * @param string $fileSystem Path to check
+ * $return boolean true/false
+ */
+ public function isWriteable($fileSystem)
+ {
+ // Clear the cache
+ clearstatcache();
+
+ // Return the status of the permission
+ return is_writable($fileSystem);
+ }
+
+ /**
+ * Function to Output an Ordered/Un-ordered list from an array. Default list type is un-ordered.
+ * @param array() $list_array An array list of data to be made into a list.
+ * @return string $list An HTML list
+ */
+ public function outputHtmlList($list_array = array(), $list_type = 'ul')
+ {
+ $list = "<$list_type>";
+ foreach ($list_array as $list_item)
+ {
+ $list .= '<li>' . $list_item .'</li>';
+ }
+ $list .= "</$list_type>";
+
+ return $list;
+ }
+
+
+ /**
+ * Function to act on all the actions during Flyspray Setup
+ * The Post variables are extracted for deciding which function to call.
+ */
+ public function processActions()
+ {
+ $action = 'index';
+ $what = '';
+
+ extract($_POST);
+
+ switch($action)
+ {
+ case 'database':
+ $this->displayDatabaseSetup();
+ break;
+
+ case 'administration':
+ // Prepare the required data
+ $required_data =
+ array(
+ 'db_hostname' => array('Database hostname', 'string', true),
+ 'db_type' => array('Database type', 'string', true),
+ 'db_username' => array('Database username', 'string', true),
+ 'db_password' => array('Database password', 'string', false),
+ 'db_name' => array('Database name', 'string', true),
+ 'db_prefix' => array('Table prefix', 'string', false),
+ );
+ if ($data = $this->checkPostedData($required_data, $message = 'Configuration Error'))
+ {
+ // Process the database checks and install tables
+ if ($this->processDatabaseSetup($data))
+ {
+ // Proceed to Administration part
+ $this->displayAdministration();
+ }
+ else
+ {
+ $_POST['action'] = 'database';
+ $this->displayDatabaseSetup();
+ }
+ }
+ else
+ {
+ $_POST['action'] = 'database';
+ $this->displayDatabaseSetup();
+ }
+ break;
+
+ case 'complete':
+ // Prepare the required data
+ $required_data = array(
+ 'db_hostname' => array('Database hostname', 'string', true),
+ 'db_type' => array('Database type', 'string', true),
+ 'db_username' => array('Database username', 'string', true),
+ 'db_password' => array('Database password', 'string', false),
+ 'db_name' => array('Database name', 'string', true),
+ 'db_prefix' => array('Table prefix', 'string', false),
+ 'admin_username' => array('Administrator\'s username', 'string', true),
+ 'admin_realname' => array('Administrator\'s realname', 'string', false),
+ 'admin_password' => array("Administrator's Password must be minimum {$this->mMinPasswordLength} characters long and", 'password', true),
+ 'admin_email' => array('Administrator\'s email address', 'email address', true),
+ 'admin_xmpp' => array('Administrator\'s jabber/xmpp address', 'xmpp address', false),
+ 'syntax_plugin' => array('Syntax', 'option', true),
+ 'reminder_daemon' => array('Reminder Daemon', 'option', false),
+ );
+ if ($data = $this->checkPostedData($required_data, $message = 'Missing config values')) {
+ // Set a page heading in case of errors.
+ $_SESSION['page_heading'] = 'Administration Processing';
+
+ if ($this->processAdminConfig($data)) {
+ $this->displayCompletion($data);
+ } else {
+ $_POST['action'] = 'administration';
+ $this->displayAdministration();
+ }
+ } else {
+ $_POST['action'] = 'administration';
+ $this->displayAdministration();
+ }
+ break;
+
+ default:
+ $this->displayPreInstall();
+ break;
+ }
+ }
+
+
+
+ public function processAdminConfig($data)
+ {
+ // Extract the variables to local namespace
+ extract($data);
+
+ if(!isset($db_password)) {
+ $db_password = '';
+ }
+ if(!isset($admin_xmpp)) {
+ $admin_xmpp = '';
+ }
+ if(!isset($admin_realname)) {
+ $admin_realname = '';
+ }
+
+ if(!isset($syntax_plugin)) {
+ $syntax_plugin = '';
+ }
+
+ $config_intro =
+ "; <?php die( 'Do not access this page directly.' ); ?>
+
+ ; This is the Flysplay configuration file. It contains the basic settings
+ ; needed for Flyspray to operate. All other preferences are stored in the
+ ; database itself and are managed directly within the Flyspray admin interface.
+ ; You should consider putting this file somewhere that isn't accessible using
+ ; a web browser, and editing header.php to point to wherever you put this file.\n";
+ $config_intro = str_replace("\t", "", $config_intro);
+
+ // Create a random cookie salt
+ $cookiesalt = md5(uniqid(mt_rand(), true));
+
+ // check to see if to enable the Reminder Daemon.
+ $daemonise = ( (isset($data['reminder_daemon'])) && ($data['reminder_daemon'] == 1) )
+ ? 1
+ : 0;
+ $db_prefix = (isset($data['db_prefix']) ? $data['db_prefix'] : '');
+
+ $config = array();
+ $config[] = "[database]";
+ $config[] = "dbtype = \"$db_type\" ; Type of database (\"mysql\", \"mysqli\" or \"pgsql\" are currently supported)";
+ $config[] = "dbhost = \"$db_hostname\" ; Name or IP of your database server";
+ $config[] = "dbname = \"$db_name\" ; The name of the database";
+ $config[] = "dbuser = \"$db_username\" ; The user to access the database";
+ $config[] = "dbpass = \"$db_password\" ; The password to go with that username above";
+ $config[] = "dbprefix = \"$db_prefix\" ; The prefix to the {$this->mProductName} tables";
+ $config[] = "\n";
+ $config[] = '[general]';
+ $config[] = "cookiesalt = \"$cookiesalt\" ; Randomisation value for cookie encoding";
+ $config[] = 'output_buffering = "on" ; Available options: "on" or "gzip"';
+ $config[] = 'passwdcrypt = "" ; Available options: "" which chooses best default (coming FS1.0: using crypt/password_hash() with blowfish), "crypt" (auto salted md5), "md5", "sha1" Note: md5 and sha1 are considered insecure for hashing passwords, avoid if possible.';
+ $config[] = "dot_path = \"\" ; Path to the dot executable (for graphs either dot_public or dot_path must be set)";
+ $config[] = "dot_format = \"png\" ; \"png\" or \"svg\"";
+ $config[] = "reminder_daemon = \"$daemonise\" ; Boolean. 0 = off, 1 = on (cron job), 2 = on (PHP).";
+ $config[] = "doku_url = \"http://en.wikipedia.org/wiki/\" ; URL to your external wiki for [[dokulinks]] in FS";
+ $config[] = 'syntax_plugin = "'.$syntax_plugin.'" ; dokuwiki, none, or html';
+ $config[] = "update_check = \"1\" ; Boolean. 0=off, 1=on";
+ $config[] = "\n";
+ $config[] = "[attachments]";
+ $config[] = "zip = \"application/zip\" ; MIME-type for ZIP files";
+ $config[] = "\n";
+ $config[] = "[oauth]";
+ $config[] = "; These are only needed if you plan to use them. You can turn them on in the admin panel.";
+ $config[] = "\n";
+ $config[] = 'github_secret = ""';
+ $config[] = 'github_id = ""';
+ $config[] = 'github_redirect = "YOURDOMAIN/index.php?do=oauth&provider=github"';
+ $config[] = 'google_secret = ""';
+ $config[] = 'google_id = ""';
+ $config[] = 'google_redirect = "YOURDOMAIN/index.php?do=oauth&provider=google"';
+ $config[] = 'facebook_secret = ""';
+ $config[] = 'facebook_id = ""';
+ $config[] = 'facebook_redirect = "YOURDOMAIN/index.php?do=oauth&provider=facebook"';
+ $config[] = 'microsoft_secret = ""';
+ $config[] = 'microsoft_id = ""';
+ $config[] = 'microsoft_redirect = "YOURDOMAIN/index.php"';
+
+ $config_text = $config_intro . implode( "\n", $config );
+
+ if (is_writable('../flyspray.conf.php') && ($fp = fopen('../flyspray.conf.php', "wb")))
+ {
+ fputs($fp, $config_text, strlen($config_text));
+ fclose($fp);
+ $this->mWriteStatus['flyspray.conf.php'] = true;
+ }
+ else
+ {
+ $this->mConfigText = $config_text;
+ $this->mWriteStatus['flyspray.conf.php'] = false;
+ }
+
+
+ // Setting the database for the ADODB connection
+ require_once($this->mAdodbPath);
+
+ # 20160408 peterdd: hack to enable database socket usage with adodb-5.20.3 . For instance on german 1und1 managed linux servers ( e.g. $db_hostname ='localhost:/tmp/mysql5.sock' )
+ if( $db_type=='mysqli' && 'localhost:/'==substr($db_hostname,0,11) ){
+ $dbsocket=substr($db_hostname,10);
+ $db_hostname='localhost';
+ ini_set( 'mysqli.default_socket', $dbsocket );
+ }
+
+ $this->mDbConnection = ADONewConnection(strtolower($db_type));
+ $this->mDbConnection->connect($db_hostname, $db_username, $db_password, $db_name);
+ $this->mDbConnection->setCharSet('utf8');
+
+ // Get the users table name.
+ $users_table = (isset($db_prefix) ? $db_prefix : '') . 'users';
+
+ $sql = "SELECT * FROM $users_table WHERE user_id = '1'";
+
+ // Check if we already have an Admin user.
+ $result = $this->mDbConnection->execute($sql);
+ if ($result)
+ {
+ // If the record exists, we update it.
+ $row = $result->fetchRow();
+ $this->mAdminUsername = $row['user_name'];
+ $this->mAdminPassword = $row['user_pass'];
+ }
+
+ $pwhash= Flyspray::cryptPassword($admin_password);
+ $update_user = "
+ UPDATE
+ $users_table
+ SET
+ user_name = ?,
+ user_pass = ?,
+ email_address = ?,
+ jabber_id = ?,
+ real_name = ?
+ WHERE
+ user_id = '1'";
+
+ $update_params = array($admin_username, $pwhash, $admin_email, $admin_xmpp, $admin_realname);
+
+ $result = $this->mDbConnection->execute($update_user, $update_params);
+
+ if (!$result)
+ {
+ $errorno = $this->mDbConnection->metaError();
+ $_SESSION['page_heading'] = 'Failed to update Admin users details.';
+ $_SESSION['page_message'][] = ucfirst($this->mDbConnection->metaErrorMsg($errorno)) . ': '. $this->mDbConnection->errorMsg($errorno);
+ return false;
+ }
+ else
+ {
+ $this->mAdminUsername = $admin_username;
+ $this->mAdminPassword = $admin_password;
+ }
+
+ return true;
+ }
+
+
+ public function processDatabaseSetup($data)
+ {
+ require_once($this->mAdodbPath);
+
+ // Perform a number of fatality checks, then die gracefully
+ if (!defined('_ADODB_LAYER'))
+ {
+ trigger_error('ADODB Libraries missing or not correct version');
+ }
+
+ # 20160408 peterdd: hack to enable database socket usage with adodb-5.20.3 . For instance on german 1und1 managed linux servers ( e.g. $data['db_hostname'] ='localhost:/tmp/mysql5.sock' )
+ if( strtolower($data['db_type'])=='mysqli' && 'localhost:/'==substr($data['db_hostname'],0,11) ){
+ $dbsocket=substr($data['db_hostname'],10);
+ $data['db_hostname']='localhost';
+ ini_set( 'mysqli.default_socket', $dbsocket );
+ }
+
+ // Setting the database type for the ADODB connection
+ $this->mDbConnection = ADONewConnection(strtolower($data['db_type']));
+ if (!$this->mDbConnection->connect(array_get($data, 'db_hostname'), array_get($data, 'db_username'), array_get($data, 'db_password'), array_get($data, 'db_name')))
+ {
+ $_SESSION['page_heading'] = 'Database Processing';
+ switch($error_number = $this->mDbConnection->metaError())
+ {
+ case '-1':
+ // We are using the unknown error code(-1) because ADOdb library may not have the error defined.
+ // It could be totally some weird error.
+ $_SESSION['page_message'][] = $this->mDbConnection->errorMsg();
+ return false;
+ break;
+
+ case '-24':
+ // Could not connect to database with the hostname provided
+ $_SESSION['page_message'][] = ucfirst($this->mDbConnection->metaErrorMsg($error_number)) . ': ' . ucfirst($this->mDbConnection->ErrorMsg($error_number));
+ $_SESSION['page_message'][] = 'Usually the database host name is "localhost". In some occassions, it maybe an internal ip-address or another host name to your webserver.';
+ $_SESSION['page_message'][] = 'Double check with your hosting provider or System Administrator.';
+ return false;
+ break;
+
+ case '-25':
+ // Database does not exist, try to create one
+ $this->mDbConnection = ADONewConnection(strtolower($data['db_type']));
+ $this->mDbConnection->connect(array_get($data, 'db_hostname'), array_get($data, 'db_username'), array_get($data, 'db_password'));
+ $dict = NewDataDictionary($this->mDbConnection);
+
+ # if possible set correct default character set for mysql.
+ # MySQL below 5.5.3 only supports 1,2,3 byte chars of utf8. But some language's chars or emojis(argh) are defined as 4byte chars
+ $mysqldbcharset='DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci'; # default for mysql for compat
+ if( $data['db_type']=='mysqli' || $data['db_type']=='mysql' ) {
+ $dbinfo=$this->mDbConnection->serverInfo(); # provides 'description' and 'version'
+ if( version_compare($dbinfo['version'], '5.5.3') >=0 ){
+ $mysqldbcharset='DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci';
+ $this->mDbConnection->setCharSet('utf8mb4');
+ }else{
+ $mysqldbcharset='DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci';
+ $this->mDbConnection->setCharSet('utf8');
+ $_SESSION['page_message'][]='Your MySQL server '.$dbinfo['version'].' < 5.5.3, so database has limited utf8 support (no unicode emojis for instance). Upgrading your MySQL server to 5.5.3 or newer is suggested.';
+ }
+ }else{
+ # postgresql
+ $this->mDbConnection->setCharSet('utf8');
+ }
+
+ $sqlarray = $dict->createDatabase(array_get($data, 'db_name'), array('mysql'=>$mysqldbcharset) );
+
+ if (!$dict->executeSQLArray($sqlarray)) {
+ $_SESSION['page_message'][] = ucfirst($this->mDbConnection->metaErrorMsg($error_number)) . ': ' . ucfirst($this->mDbConnection->ErrorMsg($error_number));
+ $_SESSION['page_message'][] = 'Your database does not exist and could not be created. Either create the database yourself, choose an existing database or
+ use a database user with sufficient permissions to create a database.';
+ return false;
+ } else {
+ $this->mDbConnection->selectDB(array_get($data, 'db_name'));
+ unset($_SESSION['page_heading']);
+ break;
+ }
+
+ case '-26':
+ // Username passwords don't match for the hostname provided
+ $_SESSION['page_message'][] = ucfirst($this->mDbConnection->metaErrorMsg($error_number)) . ': ' . ucfirst($this->mDbConnection->ErrorMsg($error_number));
+ $_SESSION['page_message'][] = "Apparently you haven't set up the right permissions for the database hostname provided.";
+ $_SESSION['page_message'][] = 'Double check the provided credentials or contact your System Administrator for further assistance.';
+ return false;
+ break;
+
+ default:
+ $_SESSION['page_message'][] = "Please verify your username/password/database details (error=$error_number)" . $this->mDbConnection->MetaErrorMsg($error_number);
+ return false;
+ break;
+ }
+ }
+ // Check that table prefix is OK, some DBs don't like it
+ $prefix = array_get($data, 'db_prefix');
+ if (strlen($prefix) > 0 && is_numeric($prefix[0])) {
+ $_SESSION['page_heading'] = 'Database Processing';
+ $_SESSION['page_message'][] = 'The table prefix may not start with a number.';
+ return false;
+ }
+
+ // Setting the Fetch mode of the database connection.
+ $this->mDbConnection->setFetchMode(ADODB_FETCH_BOTH);
+
+ if( $data['db_type']=='mysqli') {
+ $dbinfo=$this->mDbConnection->serverInfo(); # provides 'description' and 'version'
+ if( version_compare($dbinfo['version'], '5.5.3') >=0 ){
+ $this->mDbConnection->setCharSet('utf8mb4');
+ }else{
+ $this->mDbConnection->setCharSet('utf8');
+ }
+ }else{
+ $this->mDbConnection->setCharSet('utf8');
+ }
+
+ //creating the datadict object for further operations
+ $this->mDataDict = NewDataDictionary($this->mDbConnection);
+
+ include_once dirname($this->mAdodbPath) . '/adodb-xmlschema03.inc.php';
+
+ $this->mXmlSchema = new adoSchema($this->mDbConnection);
+
+ // Populate the database with the new tables and return the result (boolean)
+ if (!$this->populateDb($data))
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Function to populate the database with the sql constructs which is in an sql file
+ * @param array $data The actual database configuration values
+ * @return boolean
+ */
+
+ public function populateDb($data)
+ {
+ // Check available upgrade scripts, use the script of very latest version
+ $folders = glob_compat(BASEDIR . '/upgrade/[0-9]*');
+ usort($folders, 'version_compare'); // start with lowest version
+ $folders = array_reverse($folders); // start with highest version
+ $sql_file = APPLICATION_PATH . '/setup/upgrade/' . reset($folders) . '/flyspray-install.xml';
+
+ $upgradeInfo = APPLICATION_PATH . '/setup/upgrade/' . reset($folders) . '/upgrade.info';
+ $upgradeInfo = parse_ini_file($upgradeInfo, true);
+
+ // Check if the install/upgrade file exists
+ if (!is_readable($sql_file)) {
+
+ $_SESSION['page_message'][] = 'SQL file required for importing structure and data is missing.';
+ return false;
+ }
+
+ // Extract the variables to local namespace
+ extract($data);
+ if (!isset($db_prefix)) {
+ $db_prefix = '';
+ }
+
+ if(is_numeric($db_prefix)) {
+ $_SESSION['page_message'][] = 'database prefix cannot be numeric only';
+ return false;
+ }
+
+ // Set the prefix for database objects ( before parsing)
+ $this->mXmlSchema->setPrefix( (isset($db_prefix) ? $db_prefix : ''), false);
+ $this->mXmlSchema->parseSchema($sql_file);
+
+ $this->mXmlSchema->executeSchema();
+
+ // Last but not least global prefs update
+ if (isset($upgradeInfo['fsprefs'])) {
+ $existing = $this->mDbConnection->getCol("SELECT pref_name FROM {$db_prefix}prefs");
+ // Add what is missing
+ foreach ($upgradeInfo['fsprefs'] as $name => $value) {
+ if (!in_array($name, $existing)) {
+ $this->mDbConnection->execute("INSERT INTO {$db_prefix}prefs (pref_name, pref_value) VALUES (?, ?)", array($name, $value));
+ }
+ }
+ // Delete what is too much
+ foreach ($existing as $name) {
+ if (!isset($upgradeInfo['fsprefs'][$name])) {
+ $this->mDbConnection->execute("DELETE FROM {$db_prefix}prefs WHERE pref_name = ?", array($name));
+ }
+ }
+ }
+
+ $this->mDbConnection->execute("UPDATE {$db_prefix}prefs SET pref_value = ? WHERE pref_name = 'fs_ver'", array($this->version));
+
+ if (($error_no = $this->mDbConnection->metaError()))
+ {
+ $_SESSION['page_heading'] = 'Database Processing';
+ switch ($error_no)
+ {
+ case '-5':
+ // If there are tables with the same name
+ $_SESSION['page_message'][] = 'Table ' .$this->mDbConnection->metaErrorMsg($this->mDbConnection->metaError());
+ $_SESSION['page_message'][] = 'There probably are tables in the database which have the same prefix you provided.';
+ $_SESSION['page_message'][] = 'It is advised to change the prefix provided or you can drop the existing tables if you don\'t need them. Make a backup if you are not certain.';
+ return false;
+ break;
+
+ case '-1':
+ // We are using the unknown error code(-1) because ADOdb library may not have the error defined.
+ $_SESSION['page_message'][] = $this->mDbConnection->errorMsg();
+ return false;
+ break;
+
+ default:
+ $_SESSION['page_message'][] = $this->mDbConnection->errorMsg() . ': ' . $this->mDbConnection->errorNo();
+ $_SESSION['page_message'][] = 'Unknown error, please notify Developer quoting the error number';
+ return false;
+ break;
+ }
+ }
+
+ return true;
+ }
+
+
+
+
+ /**
+ * Function to return status of boolean results in html format
+ * @param boolean $boolean The status of the result in True/False form
+ * @param string $type The type of html format to return
+ * @return string Depending on the type of format to return
+ */
+ public static function returnStatus($boolean, $type = 'yes')
+ {
+ // Do a switch on the type of status
+ switch($type)
+ {
+ case 'yes':
+ return ($boolean)
+ ? '<span class="green">'.L('yes').'</span>'
+ : '<span class="red">'.L('no').'</span>';
+ break;
+
+ case 'available':
+ return ($boolean)
+ ? '<span class="green">'.L('available').'</span>'
+ : '<span class="red">'.L('missing').'</span>';
+ break;
+
+ case 'writeable':
+ return ($boolean)
+ ? '<span class="green">'.L('writeable').'</span>'
+ : '<span class="red">'.L('unwriteable').'</span>';
+ break;
+
+ case 'on':
+ return ($boolean)
+ ? '<span class="green">'.L('on').'</span>'
+ : '<span class="red">'.L('off').'</span>';
+ break;
+ case 'support':
+ return ($boolean)
+ ? '<span class="green">'.L('supported').'</span>'
+ : '<span class="red">'.L('x').'</span>';
+ break;
+ default:
+ return ($boolean)
+ ? '<span class="green">'.L('true').'</span>'
+ : '<span class="red">'.L('false').'</span>';
+ break;
+ }
+ }
+
+ /**
+ * To verify if a string was empty or not.
+ *
+ * Usually used to validate user input. If the user has inputted empty data
+ * or just blank spaces, we need to trim of such empty data and see if
+ * anything else is left after trimming. If there is data remaining, then
+ * the return value will be greater than 0 else it will be 0 (zero) which
+ * equates to a true/false scenario
+ *
+ * @param string $arg The data to be checked
+ *
+ * @return The result of the check.
+ */
+ public function trimArgs($arg)
+ {
+ return strlen(trim($arg));
+ }
+
+ public function verifyVariableTypes($type, $value)
+ {
+ $message = '';
+ switch($type)
+ {
+ case 'string':
+ return is_string($value);
+ break;
+
+ case 'number':
+ return is_numeric($value);
+ break;
+
+ case 'xmpp address':
+ case 'email address':
+ return filter_var($value, FILTER_VALIDATE_EMAIL);
+ break;
+
+ case 'boolean':
+ return (bool) $value;
+ break;
+
+ case 'password':
+ return (strlen($value) >= $this->mMinPasswordLength);
+ break;
+
+ case 'folder':
+ return is_dir($value);
+ break;
+
+ default:
+ return true;
+ break;
+ }
+ }
+
+ /**
+ * Function to output the templates
+ * @param array $templates The collection of templates with their associated variables
+ *
+ */
+ public function outputPage($templates = array())
+ {
+ if (sizeof($templates) == 0)
+ {
+ trigger_error("Templates not configured properly", E_USER_ERROR);
+ }
+
+ // Define a set of common variables which plugin to the structure template.
+ $page = new Tpl;
+ $body = '';
+
+ // Loop through the templates array to dynamically create objects and assign variables to them.
+ /// XXX: this is not a common way to use our template class, but I didn't want to rewrite
+ /// the whole setup only to change the templating engine
+ foreach($templates as $name => $module)
+ {
+ foreach ($module['vars'] as $var_name => $value) {
+ $page->assign($var_name, $value);
+ }
+
+ if ($name == 'structure') {
+ $page->assign('body', $body);
+ $page->display('structure.tpl');
+ } else {
+ $body .= $page->fetch($module['template']);
+ }
+ }
+ }
+}
+
+//start the installer, it handles the rest inside the class
+new Setup();
diff --git a/setup/lang/de.php b/setup/lang/de.php
new file mode 100644
index 0000000..2d76ae0
--- /dev/null
+++ b/setup/lang/de.php
@@ -0,0 +1,22 @@
+<?php
+$translation=array(
+'available' => 'verfügbar',
+'missing' => 'fehlt',
+'needcomposer' => 'Flyspray benötigt einige zusätzliche Programmbibliotheken, die mit Composer installiert werden können.',
+'no' => 'nein',
+'installcomposer' => 'Starte Composer',
+'performupgrade' => 'Aktualisierung durchführen',
+'precautions' => 'Vorsichtsmaßnahmen',
+'precautionbackup' => 'Erstelle eine Sicherung deiner Datenbank und aller zu Flyspray gehörenden Dateien vor der Aktualisierung',
+'preconditionchecks' => 'Voraussetzungen',
+'proceedtodbsetup' => 'weiter zu den Datenbankeinstellungen',
+'recommended' => 'empfohlen',
+'supported' => 'unterstützt',
+'upgrade' => 'Aktualisierung',
+'upgradepossible' => 'Eine Aktualisierung ist möglich.',
+'versioncompare' => 'Deine derzeitige Flysprayversion ist %s und es kann auf Version %s aktualisiert werden.',
+'writeable' => 'schreibbar',
+'writeaccessconf' => 'Um Flyspray zu aktualisieren muß Lese- und Schreibrecht für flyspray.conf.php existieren.',
+'yes' => 'ja',
+);
+?>
diff --git a/setup/lang/en.php b/setup/lang/en.php
new file mode 100644
index 0000000..e848e9b
--- /dev/null
+++ b/setup/lang/en.php
@@ -0,0 +1,101 @@
+<?php
+$language=array(
+'needcomposer' => 'You need some required libraries installed by Composer.',
+'installcomposer' => 'Run Composer',
+'performupgrade' => 'Perform Upgrade',
+'precautions' => 'Precautions',
+'precautionbackup' => 'Create a backup of your database and all Flyspray related files before performing the upgrade.',
+'preconditionchecks' => 'Precondition checks',
+'upgrade' => 'Upgrade',
+'upgradepossible' => 'Apparently, an upgrade is possible.',
+'versioncompare' => 'Your current version is %s and the version we can upgrade to is %s.',
+'writeaccessconf' => 'In order to upgrade Flyspray correctly it needs to be able to access and write flyspray.conf.php.',
+'adminemail' => 'Admin Email Address',
+'adminxmpp' => 'Admin Jabber Address',
+'adminusername' => 'Admin Username',
+'adminrealname' => 'Admin Realname',
+'adminpassword' => 'Admin Password',
+'slogan' => 'The bug Killer!',
+'progress' => 'Progress',
+'documents' => 'Docs',
+'preinstallcheck' => 'Pre-installation Check',
+'databasesetup' => 'Database Setup',
+'administration' => 'Administration',
+'installflyspray' => 'Install Flyspray',
+'libcheck' => 'PHP and Supported Libraries',
+'libchecktext' => 'To make setup possible, you must have a correct PHP version installed and <strong>at least one</strong> supported database.',
+'recsettings' => 'Recommended Settings',
+'recsettingstext1' => 'These settings are recommended for PHP in order to ensure full compatibility with Flyspray.',
+'recsettingstext2' => 'However, Flyspray will still operate if your settings do not quite match the recommended shown here.',
+'dirandfileperms' => 'Directory and File Permissions',
+'dirandfilepermstext'=> 'In order for Flyspray to function correctly it needs to be able to access or write to certain files or directories. If you see "Unwriteable" you need to change the permissions on the file or directory to allow Flyspray to write to it.',
+'proceedtodbsetup' => 'Proceed to Database Setup',
+'proceedtodbsetuptext'=>'All configurations seems to be in place. You may proceed to the Database Setup page.',
+'library' => 'library',
+'status' => 'status',
+'database' => 'database',
+'recommended' => 'Recommended',
+'actual' => 'Actual',
+'yes' => 'Yes',
+'no' => 'No',
+'explainwhatandwhyheader' => 'Formatting of task descriptions and comments has changed',
+'explainwhatandwhycontent' => 'Previously those installations of Flyspray that didn\'t use dokuwiki formatting engine stored data as plain text. '
+ . 'We now use HTML as the default and can try to add paragraph and line break tags to already existing data entries, so your data retains it\'s '
+ . 'structure. But if your existing data already contains manually added HTML tags something probably goes wrong and you have some corrupted '
+ . 'entries in your database that must be manually fixed. If unsure, answer "No", unless you can examine the situation before proceeding. '
+ . 'If you are fluent in programming with PHP, see also at the end of setup/upgrade.php, look at what it does and possibly modify according to '
+ . 'your needs. ',
+'databaseconfiguration'=>'Database Configuration for ',
+'proceedtoadmin'=>'Proceed to Administration setup',
+'databasehostname'=>'database hostname',
+'databasehostnamehint'=>'Enter the <strong>database hostname</strong> of the server Flyspray is to be installed on. This is usually "localhost" or an IP.',
+'databasetype'=>'database type',
+'databasetypehint'=>'Choose the <strong>database type</strong>. If you have both the choice between MySQL driver and MySQLi driver, use MySQLi. The old MySQL driver (mysql_*) is deprecated in PHP since a long time. If you have MariaDB as MySQL replacement, select MySQLi.',
+'databasename'=>'database name',
+'databasenamehint'=>'Insert a name of an existing database or a new name. If the database not exists, Flyspray tries to create that database for you. Use simple names like "flyspray".',
+'databaseusername'=>'database username',
+'databaseusernamehint'=>'Enter the <strong>database username and password</strong>.
+Flyspray requires that you have a database setup with a username and password to install the database schema.
+If you are not sure about these details, please consult with your administrator or web hosting provider.
+(Local xampp or wampp servers default installs could work with "root" and an empty password field)',
+'databasepassword'=>'database password',
+'databasepasswordhint'=>'',
+'tableprefix'=>'table prefix',
+'tableprefixhint'=>'Optional table prefix to avoid collisions with existing tables. "flyspray_" or "fs_" are good choices.',
+'next'=>'Next',
+'showpassword' => 'Show Password',
+'lgpllicense' => 'LGPL License',
+'installationguide' => 'Install Guide',
+'developermanual' => "Developer's Manual",
+'supported' => 'Supported',
+'inphp' => 'in PHP',
+'available' => 'Available',
+'missing' => 'Missing',
+'writeable' => 'Writeable',
+'unwriteable' => 'Un-writeable',
+'on' => 'ON',
+'off' => 'OFF',
+'x' => 'X',
+'true' => 'True',
+'false' => 'False',
+'directive' => 'Directive',
+'enable' => 'Enable',
+'disable' => 'Disable',
+'administrationsetup' => 'Administration setup',
+'setupapplicationvalue' => 'Setup all the Application values',
+'adminsetuptip1' => 'The Database schema has been populated. Please follow the instructions to complete the Admin configuration.',
+'adminsetuptip2' => '1) Admin <strong>Email, Username, Password</strong> are values for the Administrator of your Flyspray Installation. You can change these values through the administration section of Flyspray.',
+'adminsetuptip3' => 'Choosing a Syntax is a setting that cannot be simply changed and is set at install for the whole Flyspray installation. Choose Text/Dokuwiki if you are unsure which you choose.',
+'syntax' => 'Syntax',
+'syntaxtext' => 'If you are unsure choose Text/Dokuwiki. The switch from dokuwiki to HTML is easy. But a switch from HTML back to dokuwiki or another text format like markdown is nearly impossible without some information loss like deep nested HTML content or formatting.',
+'scheduletitle' => 'You can setup a crontab entry that calls scheduler.php in a time interval. This setting can be switched on/off everytime in Flyspray admin section.',
+'enablescheduling' => 'Enable scheduling',
+'proceedtofinalsetup' => 'Proceed to final Setup',
+'proceedtofinalsetuptext' => 'Proceed to complete Flyspray setup.',
+'installstatus' => 'Install status',
+'congratulations' => 'Congratulations! Flyspray is now installed and ready to use.',
+'removesetupdirectory' => 'Please remove the setup directory now.',
+'viewsite' => 'View Site',
+'proceedtoindex' => 'Proceed to Flyspray index',
+);
+?>
diff --git a/setup/lang/es.php b/setup/lang/es.php
new file mode 100644
index 0000000..2fb4874
--- /dev/null
+++ b/setup/lang/es.php
@@ -0,0 +1,100 @@
+<?php
+$language=array(
+'installFSdevelop' => 'Parece que estás instalando una versión de desarrollo de Flyspray.',
+'needcomposer' => 'Es necesario instalar algunas librerías usando Composer.',
+'installcomposer' => 'Ejecutar Composer',
+'performupgrade' => 'Perform Upgrade',
+'precautions' => 'Advertencias',
+'precautionbackup' => 'Antes de actualizar se recomienta realizar una copia de seguridad de ficheros y base de datos de FlySpray.',
+'preconditionchecks' => 'Precondition checks',
+'upgrade' => 'Actualizar',
+'upgradepossible' => 'Parece que hay una actualización disponible',
+'versioncompare' => 'Your current version is %s and the version we can upgrade to is %s.',
+'writeaccessconf' => 'Para actualizar Flyspray el fichero <pre>flyspray.conf.php</pre> debe tener permisos de escritura',
+'adminemail' => 'Email del administrador',
+'adminusername' => 'Usuario administrador',
+'adminpassword' => 'Contraseña del administrador',
+'slogan' => 'The bug Killer!',
+'progress' => 'Progress',
+'documents' => 'Docs',
+'preinstallcheck' => 'Pre-instalacion',
+'databasesetup' => 'Base de Datos',
+'administration' => 'Aplicación',
+'installflyspray' => 'Instalación Flyspray',
+'libcheck' => 'PHP y módulos requeridos',
+'libchecktext' => 'Para poder completar correctamente la instalación de FlySpray, debes tener instalado una versión de PHP y <strong>al menos una</strong> base de datos compatible.',
+'recsettings' => 'Configuración recomendada',
+'recsettingstext1' => 'A continuación se indica la configuración de PHP recomendada para asegurar la compatibilidad de Flyspray.',
+'recsettingstext2' => 'Nota: No obstante, es posible que FlySpray funcione con una configuración diferente a la recomendada.',
+'dirandfileperms' => 'Permisos en carpetas y ficheros',
+'dirandfilepermstext'=> 'Para poder utilizar Flyspray se necesita tener acceso de escritura en determinados ficheros y carpetas.
+ Si se muestra el mensaje "Sin permiso de escritura" será necesario cambiar los permisos de forma que el servidor de Flyspray pueda escribir en ellos',
+'proceedtodbsetup' => 'Ir a Configuración de Base de Datos',
+'proceedtodbsetuptext'=>'Cuando la configuración sea correcta, continua al siguiente paso para configurar la base de datos.',
+'library' => 'Módulo',
+'status' => 'Estado',
+'database' => 'Base de datos',
+'recommended' => 'Recomendada',
+'actual' => 'Actual',
+'yes' => 'Sí',
+'no' => 'No',
+'explainwhatandwhyheader' => 'Formatting of task descriptions and comments has changed',
+'explainwhatandwhycontent' => 'Previously those installations of Flyspray that didn\'t use dokuwiki formatting engine stored data as plain text. '
+ . 'We now use HTML as the default and can try to add paragraph and line break tags to already existing data entries, so your data retains it\'s '
+ . 'structure. But if your existing data already contains manually added HTML tags something probably goes wrong and you have some corrupted '
+ . 'entries in your database that must be manually fixed. If unsure, answer "No", unless you can examine the situation before proceeding. '
+ . 'If you are fluent in programming with PHP, see also at the end of setup/upgrade.php, look at what it does and possibly modify according to '
+ . 'your needs. ',
+'databaseconfiguration'=>'Configuración de la Base de Datos para ',
+'proceedtoadmin'=>'Ir a la Configuración del Administrador',
+'databasehostname'=>'Servidor ',
+'databasehostnamehint'=>'Introduce el <strong>host del servidor </strong> de base de datos donde se instalará la BDD de Flyspray. Normalmente se usa "localhost" o una dirección IP.',
+'databasetype'=>'Tipo ',
+'databasetypehint'=>'Selecciona el <strong>tipo de base de datos</strong>. Si están disponible las opciones MySQL y MySQLi, seleccione esta última. Idem si su base de datos es MariaDB en lugar de MySQL',
+'databasename'=>'Esquema (nombre)',
+'databasenamehint'=>'Introduce el nombre de la base de datos (esquema). Si no existe Flyspray intentará crearlo por ti. Nota: Usa nombres simples sin espacios, ej. "flyspray".',
+'databaseusername'=>'Usuario',
+'databaseusernamehint'=>'Introduce <strong>el usuario y contraseña de la base de datos</strong>.
+El configurador de Flyspray requiere un usuario que tenga permisos para crear el esquema de base de datos.
+Si no estás seguro, por favor, consulta con tu administrador o proveedor de hosting.
+Nota: Los servidores Xampp o Wampp, por defecto, se instalan con un usuario "root" sin password (vacío)',
+'databasepassword'=>'Contraseña',
+'databasepasswordhint'=>'',
+'tableprefix'=>'Prefijo de las tablas',
+'tableprefixhint'=>'[Opcional] puedes indicar un prefijo para evitar la colisión con tablas existentes. Se recomienda "flyspray_" o "fs_"',
+'next'=>'Next',
+'showpassword' => 'Mostrar Password',
+'lgpllicense' => 'Licencia LGPL',
+'installationguide' => 'Guía de instalación',
+'developermanual' => "Manual del desarrollador",
+'supported' => 'Soportado',
+'inphp' => 'en PHP',
+'available' => 'Sí',
+'missing' => '--',
+'writeable' => 'Escribible',
+'unwriteable' => 'Sin permiso de escritura',
+'on' => 'ON',
+'off' => 'OFF',
+'x' => 'X',
+'true' => 'Verdadero',
+'false' => 'Falso',
+'directive' => 'Directiva',
+'enable' => 'Activo',
+'disable' => 'Desactivado',
+'administrationsetup' => 'Configuración de la aplicación',
+'setupapplicationvalue' => '',
+'adminsetuptip1' => 'El esquema de base de datos de Flyspray ha sido creado. Por favor, sigue las instrucciones para completar la configuración de la aplicación.',
+'adminsetuptip2' => '1) Introduce los valores de <strong>Usuario, correo electrónico y contraseña</strong> del usuario administrador de Flyspray. Puedes cambiar estos valores desde en la sección de administración de Flyspray.',
+'adminsetuptip3' => '2) Selecciona el formado de documentación. Importante: este valor es configurado durante la instalación y no puede ser cambiado posteriormente. Selecciona Text/Dokuwiki si no estás seguro de cual elegir.',
+'syntaxtext' => 'Sintaxis<br>Selecciona Text/docuwiki si no estás seguro de cual elegir. Nota: El cambio de dokuwiki a Html es sencillo. Sin embargo el cambio de Html a dokuwiki u otro formato (como markdown) conlleva pérdidas de información, tanto contenido como formato.',
+'scheduletitle' => 'Recuerda añadir una entrada en el crontab que llame al script "scheduler.php" de forma periódica. El planificador puede ser activado/desactivado desde la sección de administración de Flyspray.',
+'enablescheduling' => 'Activar planificador de tareas',
+'proceedtofinalsetup' => 'Finalizar instalación',
+'proceedtofinalsetuptext' => 'Continua para completar la instalación de Flyspray.',
+'installstatus' => 'Estado de la instalación',
+'congratulations' => 'Enhorabuena! Flyspray está instalado y listo para usar.',
+'removesetupdirectory' => 'Por favor, borra el directorio setup antes de seguir.',
+'viewsite' => 'Finalizar y acceder a Flyspray',
+'proceedtoindex' => 'Ir a la página principal de Flyspray',
+);
+?>
diff --git a/setup/lang/fr.php b/setup/lang/fr.php
new file mode 100644
index 0000000..ffd5091
--- /dev/null
+++ b/setup/lang/fr.php
@@ -0,0 +1,14 @@
+<?php
+$language=array(
+'needcomposer' => 'Vous avez besoin de certaines librairies installées par Composer.',
+'installcomposer' => 'Lancer Composer',
+'performupgrade' => 'Procéder à la mise à jour',
+'precautions' => 'Précautions',
+'precautionbackup' => 'Créez une sauvegarde de votre base de données ainsi que de tous les fichiers de Flyspray avant tout mise à jour.',
+'preconditionchecks' => 'Contrôle des préconditions',
+'upgrade' => 'Mise à jour',
+'upgradepossible' => 'Apparemment la mise à jour n\'est pas possible.',
+'versioncompare' => 'Votre version actuelle est %s et la version vers laquelle nous pouvons mettre à jour est %s.',
+'writeaccessconf' => 'Afin de mettre à jour correctement Flyspray, nous avons besoin d\'accéder en lecture et écriture le fichier flyspray.conf.php.',
+);
+?>
diff --git a/setup/lang/it.php b/setup/lang/it.php
new file mode 100644
index 0000000..9e4f3eb
--- /dev/null
+++ b/setup/lang/it.php
@@ -0,0 +1,100 @@
+<?php
+$language=array(
+'needcomposer' => 'Sono richieste alcune librerie installate da Composer.',
+'installcomposer' => 'Esegui Composer',
+'performupgrade' => 'Esegui Aggiornamento',
+'precautions' => 'Attenzione',
+'precautionbackup' => 'Crea un backup del database e di tutti i file relativi a Flyspray prima di eseguire l\'aggiornamento',
+'preconditionchecks' => 'Verifica dei prerequisiti',
+'upgrade' => 'Aggiorna',
+'upgradepossible' => 'Sembra che sia possibile aggiornare.',
+'versioncompare' => 'La tua versione installata è %s e la versione a cui si può aggiornare è %s.',
+'writeaccessconf' => 'Per essere aggiornato correttamente Flyspray deve avere i diritti di lettura e scrittura su flyspray.conf.php.',
+'adminemail' => 'Indirizzo Email di Admin',
+'adminxmpp' => 'Indirizzo Jabber di Admin',
+'adminusername' => 'Username di Admin',
+'adminrealname' => 'Nome Reale di Admin',
+'adminpassword' => 'Password di Admin',
+'slogan' => 'The bug Killer!',
+'progress' => 'Avanzamento',
+'documents' => 'Documentazione',
+'preinstallcheck' => 'Verifiche Preliminari',
+'databasesetup' => 'Impostazione Database',
+'administration' => 'Amministrazione',
+'installflyspray' => 'Installa Flyspray',
+'libcheck' => 'PHP e Librerie Supportate',
+'libchecktext' => 'Per eseguire l\'installazione devi avere la versione corretta di PHP ed <strong>almeno uno</strong> dei database supportati.',
+'recsettings' => 'Impostazioni Consigliate',
+'recsettingstext1' => 'Queste sono le impostazioni di PHP consigliate per la piena compatibilità con Flyspray.',
+'recsettingstext2' => 'Ad ogni modo, Flyspray può funzionare anche se le tue impostazioni non sono totalmente corrispondenti a quelle consigliate.',
+'dirandfileperms' => 'Permessi per File e Directory',
+'dirandfilepermstext'=> 'Per funzionare correttamente Flyspray deve avere accesso, a volte anche in scrittura, ad alcuni file e directory. Se vedi la scritta "Non scrivibile" devi cambiare i permessi sul file o la directory corrispondente per consentirne l\'accesso a Flyspray.',
+'proceedtodbsetup' => 'Prosegui con il Setup del Database',
+'proceedtodbsetuptext'=>'Tutte le configurazioni sembrano corrette. Puoi proseguire con l\'impostazione del database',
+'library' => 'Libreria',
+'status' => 'Stato',
+'database' => 'database',
+'recommended' => 'Consigliato',
+'actual' => 'Attuale',
+'yes' => 'Sì',
+'no' => 'No',
+'explainwhatandwhyheader' => 'La formattazione nella descrizione dei task e nei commenti è cambiata',
+'explainwhatandwhycontent' => 'Precedentemente, le installazioni di Flyspray che non usavano il motore di formattazione di Dokuwiki memorizzavano i dati come testo semplice. '
+ . 'Adesso utilizziamo HTML come default e proviamo ad aggiungere i tag di paragrafo e a capo ai dati preesitenti così i tuoi dati mantengono '
+ . 'la propria struttura. Se i tuoi dati contengono già dei tag HTML inseriti manualmente, c\'è il rischio che qualcosa possa andare storto e risulti in dati corrotti '
+ . 'nel database che andranno poi corretti manualmente. Se non sei sicuro, rispondi "No", a meno che tu non sia in grado di analizzare la situazione prima di procedere. '
+ . 'Se sai programmare in PHP, esamina la parte finale dello script setup/upgrade.php, guarda cosa fa ed eventualmente modificalo in base alle tue necessità.',
+'databaseconfiguration'=>'Configurazione Database per ',
+'proceedtoadmin'=>'Prosegui con il Setup Amministrazione',
+'databasehostname'=>'Hostname',
+'databasehostnamehint'=>'Inserisci l\'<strong>hostname del database</strong> su cui stai installando Flyspray. Di solito è "localhost" o un indirizzo IP.',
+'databasetype'=>'Tipo DB',
+'databasetypehint'=>'Seleziona il <strong>tipo di database</strong>. Se hai installati entrambi i driver MySQL e MySQLi, <strong>usa MySQLi</strong>. Il vecchio driver MySQL (mysql_*) è stato deprecato in PHP da tempo immemore. Se hai MariaDB al posto di MySQL, seleziona comunque MySQLi.',
+'databasename'=>'Nome del DB',
+'databasenamehint'=>'Inserisci il nome di un database esistente o un nuovo nome. Se il database non esiste, Flyspray tenterà di crearlo. È consigliabile un nome semplice tipo "flyspray".',
+'databaseusername'=>'Nome Utente',
+'databaseusernamehint'=>'Inserisci il <strong>nome utente e la password per il database</strong>.
+Flyspray richiede un database impostato con nome utente e password per installarvi lo schema.
+Se non sei sicuro di questi parametri, chiedi all\'amministratore del database o al tuo hosting provider.
+(A volte le installazioni locali di XAMPP o WAMPP sono configurate di default come "root" con password vuota)',
+'databasepassword'=>'Password',
+'databasepasswordhint'=>'',
+'tableprefix'=>'Prefisso per le Tabelle',
+'tableprefixhint'=>'Prefisso opzionale per le tabelle al fine di evitare conflitti con eventuali tabelle già esistenti. È consigliabile un prefisso semplice come "flyspray_" o "fs_" .',
+'next'=>'Prossimo',
+'showpassword' => 'Mostra la Password',
+'lgpllicense' => 'Licenza LGPL',
+'installationguide' => 'Guida all\'Installazione',
+'developermanual' => "Manuale per Sviluppatori",
+'supported' => 'Supportato',
+'inphp' => 'in PHP',
+'available' => 'Disponibile',
+'missing' => 'Mancante',
+'writeable' => 'Scrivibile',
+'unwriteable' => 'Non scrivibile',
+'on' => 'ON',
+'off' => 'OFF',
+'x' => 'X',
+'true' => 'Vero',
+'false' => 'Falso',
+'directive' => 'Direttiva',
+'enable' => 'Abilita',
+'disable' => 'Disabilita',
+'administrationsetup' => 'Impostazione Amministrazione',
+'setupapplicationvalue' => 'Impostazione di tutti i valori dell\'Applicazione',
+'adminsetuptip1' => 'Lo schema del database è stato configurato. Segui le istruzioni per completare le impostazioni di Amministrazione.',
+'adminsetuptip2' => '1) <strong>Email, Nome Utente e Password</strong> di Admin sono per l\'Amministratore della tua installazione di Flyspray. Puoi modificare questi valori dalla sezione di amministrazione di Flyspray.',
+'adminsetuptip3' => 'L\'impostazione di una Sintassi non è semplice da cambiare una volta installato Flyspray perciò viene impostata globalmente all\'atto dell\'installazione. Se non sei sicuro su cosa scegliere, seleziona Text/Dokuwiki.',
+'syntax' => 'Sintassi',
+'syntaxtext' => 'Se non sei sicuro, seleziona Text/Dokuwiki. Il cambio da Dokuwiki a HTML è semplice. Invece, cambiare successivamente da HTML a Dokuwiki o un altro formato come Markdown, è praticamente impossibile senza la perdita di alcune informazioni come HTML fortemente nidifcati o altra formattazione.',
+'scheduletitle' => 'Puoi impostare un crontab che richiamerà scheduler.php a intervalli di tempo predefiniti. Questa impostazione può essere abilitata e disabilitata a piacere dalla sezione di amministrazione di Flyspray.',
+'enablescheduling' => 'Abilita la schedulazione',
+'proceedtofinalsetup' => 'Prosegui con il Setup finale',
+'proceedtofinalsetuptext' => 'Prosegui per completare l\'installazione di Flyspray.',
+'installstatus' => 'Stato dell\'Installazione',
+'congratulations' => 'Congratulazioni! Flyspray è stato installato ed è pronto all\'uso.',
+'removesetupdirectory' => 'Ricordati di eliminare la directory setup ora.',
+'viewsite' => 'Visualizza il Sito',
+'proceedtoindex' => 'Vai alla pagina principale di Flyspray',
+);
+?>
diff --git a/setup/lang/zh_cn.php b/setup/lang/zh_cn.php
new file mode 100644
index 0000000..9a82dab
--- /dev/null
+++ b/setup/lang/zh_cn.php
@@ -0,0 +1,46 @@
+<?php
+$translation=array(
+'needcomposer' => '请先通过 Composer 来安装一些依赖库。',
+'installcomposer' => '运行 Composer',
+'upgrade' => '升级',
+'adminemail' => '管理员邮箱',
+'adminusername' => '管理员帐户',
+'adminpassword' => '管理员密码',
+'progress' => '安装进度',
+'documents' => '文档',
+'preinstallcheck' => '运行环境检查',
+'databasesetup' => '数据库设置',
+'administration' => '管理员设置',
+'install' => '安装',
+'libcheck' => 'PHP和数据库',
+'libchecktext' => '在开始设置前,必须安装好合适的PHP版本,并且<strong>最少</strong>要支持一种数据库。',
+'recsettings' => '推荐设置项',
+'recsettingstext1' => '为了使Flyspray获得更好的兼容性,建议参考此处的 PHP 配置。',
+'recsettingstext2' => '当然,即使你的PHP环境配置和此处不同,Flyspray 仍然可以正常工作。',
+'dirandfileperms' => '目录和文件权限',
+'proceedtodbsetup' => '前往数据库设置',
+'library' => '库',
+'status' => '状态',
+'database' => '数据库',
+'recommended' => '推荐',
+'actual' => '实际',
+'yes' => '是',
+'no' => '否',
+'databaseconfiguration'=> '数据库连接设置,版本:',
+'proceedtoadmin'=> '前往管理员设置',
+'databasehostname'=> '数据库主机',
+'databasehostnamehint' => '请输入<strong>数据库主机名</strong>,通常可能是 "localhost" 或者 IP 地址。',
+'databasetype' => '数据库类型',
+'databasename' => '数据库名',
+'databaseusername' => '用户名',
+'databasepassword' => '密码',
+'tableprefix' => '表前缀',
+'next' => '下一步',
+'showpassword' => '显示密码',
+'lgpllicense' => 'LGPL协议',
+'installationguide' => '安装手册',
+'developermanual' => '开发者手册',
+'writeable' => '可写',
+'unwriteable' => '不可写',
+);
+?>
diff --git a/setup/styles/setup.css b/setup/styles/setup.css
new file mode 100644
index 0000000..00a8014
--- /dev/null
+++ b/setup/styles/setup.css
@@ -0,0 +1,177 @@
+body {
+ margin:0; padding:0;
+ font-family: Verdana, sans-serif;
+ font-size:13px;
+}
+a { text-decoration: none; }
+input:required {border: 1px solid #f90;}
+
+#header {
+ /*background-color:#47617B;*/
+ background-color:#5e5e5e; /* matching grayscale brightness of title.png */
+ margin:0;
+ padding:0;
+ border-bottom:4px solid #5f9729;
+}
+#logo {
+ background-image:url(../images/title.png);
+ background-position: 10px 10px;
+ background-repeat: no-repeat;
+ background-attachment:scroll;
+
+ -webkit-filter: grayscale(100%);
+ -moz-filter: grayscale(100%);
+ -o-filter: grayscale(100%);
+ filter: gray; /* IE6-9 */
+ filter: grayscale(100%); /* grayscale until a transparent logo exists that match colors of default theme */
+}
+#logo h1 {
+ padding:0;
+ margin:0;
+ font-size:2em;
+ line-height: 90px;
+ font-weight:normal;
+}
+#logo h1 a {
+ display: block;
+ height: 90px;
+ color:#fff;
+ border: 0;
+ padding: 0;
+ margin: 0 auto;
+ padding-left:260px;
+}
+#content {max-width:800px;margin-left:auto;margin-right:auto;}
+
+#footer {
+ background-color: #333;
+ padding: 1em;
+ margin:0;
+ border-top: 2px solid #5f9729;
+ text-align: center;
+ color:#ccc;
+}
+#footer p, #footer ul{display:inline-block;}
+#footer li {display:inline-block; list-style:none;}
+#footer a{ display:inline-block; padding:0.5em; color:#fff; }
+#footer a:hover {background-color:#000;}
+
+#stepbar{ margin-top:1em;}
+#stepbar div {
+ box-sizing:border-box;
+ height:36px;
+ font-weight: bold;
+ padding: 10px;
+ background-color:#ddd;
+ margin-right:10px;
+ margin-bottom:6px; /* when it wraps on small displays */
+ display:inline-block;
+ position:relative; /* for the :after rightarrow */
+}
+
+#stepbar .step-on { background-color:#5f9729; color:#fff;}
+#stepbar .done { background-color:#333; color:#ccc;}
+
+/* css arrow to right */
+#stepbar div:after{
+ position:absolute;
+ content:"";
+ width:0;
+ height:0;
+ top:0;
+
+ border-top:18px solid transparent;
+ border-bottom:18px solid transparent;
+ border-left:8px solid #ddd;
+ right:-8px;
+}
+
+#stepbar div::before {
+ position: absolute;
+ content: "";
+ height: 0;
+ width: 0;
+ top: 0;
+
+ border-bottom: 18px solid #ddd;
+ border-top: 18px solid #ddd;
+ border-left: 8px solid transparent;
+ left:-8px;
+}
+#stepbar .step-on::after{border-left-color:#5f9729;}
+#stepbar .step-on::before{border-top-color:#5f9729;border-bottom-color:#5f9729;}
+#stepbar .done::after{border-left-color:#333;}
+#stepbar .done::before{border-top-color:#333;border-bottom-color:#333;}
+#stepbar div:first-child::before{display:none;}
+
+.install {
+ margin-left: auto;
+ margin-right: auto;
+ margin-bottom: .5em;
+ padding: 10px;
+ border: 1px solid #ddd;
+ max-width: 700px;
+ background-color: #f1f1f1;
+}
+
+.formBlock {
+ border: 1px solid #ddd;
+ padding:5px;
+ margin:5px;
+ background: #f1f1f1;
+ color:#000;
+}
+
+.formBlock td {
+ vertical-align:top;
+ padding-top:1.5em;
+ min-width:150px;
+}
+
+.button {
+ display: block;
+ font-size: 3em;
+ margin: 0.5em auto;
+ cursor:pointer;
+}
+
+.error {
+ color : #c00;
+ font-weight : bold;
+ padding-top: 10px;
+ padding-bottom: 10px;
+}
+
+.red {
+ color:#F00;
+}
+.orange {
+ color:#FFA500;
+}
+.green {
+ color:#078843;
+}
+
+.install h1 {
+ color:#47617B;
+ text-align:center;
+}
+.install h2 {
+ color:#688EB4;
+}
+
+h1.error {
+ background-image: url(../images/exclamation.png);
+ border:none;
+ text-indent: 45px;
+ background-position: 0px 0px;
+ background-repeat: no-repeat;
+ text-align:left;
+}
+
+.box {
+ border: 5px solid #688EB4;
+ padding:0;
+ margin:0;
+ background-color: #F1F3F5;
+}
diff --git a/setup/styles/theme.css b/setup/styles/theme.css
new file mode 100644
index 0000000..a52f3e3
--- /dev/null
+++ b/setup/styles/theme.css
@@ -0,0 +1,994 @@
+@media screen {
+
+html {
+ margin : 0px;
+ padding : 0px;
+}
+
+body {
+ margin : 0px;
+ padding : 0px;
+ background-color : #F5F9FD;
+ color : #000;
+ font-size : 12px;
+ font-family : Helvetica, Verdana, sans-serif;
+}
+
+img {
+ border : none;
+}
+
+a {
+ text-decoration : none;
+}
+
+a:link {
+ color : #47617b;
+ background-color : transparent;
+ font-weight : bold;
+}
+
+a:visited {
+ color : #47617b;
+ background-color : transparent;
+ font-weight : bold;
+}
+
+a:hover {
+ color : #6395c8;
+ background-color : transparent;
+ text-decoration : none;
+}
+
+/* offsite is only used for the link to the Flyspray homepage */
+a.offsite:after {
+ content : "\2197";
+}
+
+h1 {
+ /*text-align : center;*/
+ font-size : 150%;
+}
+
+/* the main title; h1 alone is also used in the popup windows. */
+h1#title {
+ margin : 0px;
+ padding : 1ex 0px;
+ background-color : #47617b;
+ background-image : url("title.png");
+ background-repeat : no-repeat;
+ height : 45px;
+}
+
+/* there is a span element within the h1 element to enable displaying
+ an image only and blanking out the span */
+h1 span {
+ display : none;
+}
+
+h2 { /* Heading for link to task list and details */
+ margin : 0px;
+ padding : 0px;
+ font-size : 150%;
+}
+
+h4 {
+ padding : 0px;
+ margin-bottom : -10px;
+}
+
+p {
+ margin : 1ex 0px;
+ padding : 0.5ex 0.5em;
+}
+
+form {
+ margin : 0px;
+ padding : 0px;
+ display : inline;
+}
+
+form p {
+ margin : 0px;
+ padding : 0px;
+}
+
+td {
+ vertical-align : top;
+}
+
+th {
+ vertical-align : top;
+}
+
+input, textarea, select, button {
+ background-color : #eef7ff;
+ color : #03008f;
+ border : 1px ridge #000000;
+ margin : 2px;
+ font-size : 100%;
+}
+
+textarea {
+ width : 95%;
+}
+
+/* labels are used nearly in every form */
+label {
+ text-align : right;
+ display : block;
+ margin-right : 8px;
+ font-weight : bold;
+ white-space : nowrap;
+/* padding : 3px 0 0 0; */
+}
+
+label.inline {
+ display : inline;
+}
+
+/* div.admin and p.admin is used for areas that only administrators can use
+ p.admin for instance for adding comments
+ table.admin serves the same purpose */
+/* table.login is the framework for the login form at the bottom of a page */
+/* table.userlist is found in the user&groups section */
+div.admin, p.admin, table.admin, table.userlist {
+ border : 1px solid #ccc;
+ margin : 1em 0px;
+ padding : 0px;
+ margin-bottom : 30px;
+ background-color : #e6eef6;
+ color : #000000;
+ font-family : Helvetica, Verdana, sans-serif;
+}
+
+div#loginbox {
+ border : 1px solid #ccc;
+ margin : 0em 0px;
+ padding : 0px;
+ background-color : #e6eef6;
+ height : 22px;
+}
+
+div#loginbox p {
+ padding : 0px;
+ margin : 0px;
+}
+
+div#loginbox em {
+ display : none;
+}
+
+div#loginbox label, div#loginbox input.maintext, div#loginbox input.mainbutton {
+ display : inline;
+ padding : 0 3px 0 3px;
+/* height : 14px; */
+}
+
+div#loginbox a {
+ padding : 0 0 0 13px;
+ text-align : center;
+}
+
+div#loginbox span#links {
+ position : absolute;
+ top : 5px;
+ right : 5px;
+}
+
+div#loginbox span#links a {
+ color : #ffffff;
+ background-color : transparent;
+ font-weight : normal;
+}
+
+/* The paragraph containing the main menu */
+p#menu {
+ border : 1px solid #ccc;
+ margin : 0em 0px;
+ padding : 4px 0 0 0;
+ background-color : #e6eef6;
+ height : 18px;
+ vertical-align : baseline;
+}
+
+p#menu a {
+ height : 18px;
+ padding : 3px 1px 3px 20px;
+ background-repeat : no-repeat;
+ background-position : 1px 1px;
+ font-size : 12px;
+ font-weight : normal;
+ vertical-align : baseline;
+}
+
+p#menu a:hover {
+ color : #6395c8;
+ background-color : transparent;
+ text-decoration : none;
+}
+
+div#anonopen {
+ position : absolute;
+ top : 30px;
+ right : 5px;
+ padding : 0px;
+}
+
+div#anonopen a {
+ color : #ffffff;
+ background-color : transparent;
+ padding : 0px;
+ font-weight : normal;
+}
+
+/* Links in menus */
+
+a#newtasklink {
+ background-image : url(menu/newtask.png);
+}
+
+a#reportslink {
+ background-image : url(menu/reports.png);
+}
+
+a#editmydetailslink {
+ background-image : url(menu/editmydetails.png);
+}
+
+a#lastsearchlink {
+ background-image : url(menu/search.png);
+}
+
+a#logoutlink {
+ background-image : url(menu/logout.png);
+}
+
+a#optionslink {
+ background-image : url(menu/options.png);
+}
+
+a#projectslink {
+ background-image : url(menu/projectprefs.png);
+}
+
+/* For pending admin requests */
+a#attention {
+ color : #ff0000;
+ background-color : #fff000;
+}
+
+table.userlist td, table.userlist th {
+ border : 1px solid #ccc;
+}
+
+/* p#showtask contains the form to search for a specific task number */
+p#showtask {
+ text-align : right;
+ width : 40%;
+ margin-left : auto;
+ position : relative;
+ top : -2em;
+}
+
+/* The paragraph containing the search form */
+div#search {
+ margin-bottom : 1em;
+ border : 1px solid #000000;
+ background-color : #e6eef6;
+}
+
+div#search p {
+ padding : 0px;
+ margin : 0px;
+}
+
+div#search span#date_d {
+ min-width : 20px;
+ margin : 0px 5px 0px 5px;
+ padding : 0px 5px 0px 5px;
+ display : inline;
+ background-color : #eef7ff;
+ color : #03008f;
+ border : 1px ridge #000000;
+ margin : 2px;
+ font-size : 100%;
+}
+
+div#search select {
+ background-color : #eef7ff;
+ color : #03008f;
+ border : 1px ridge black;
+}
+
+div#search em {
+ float : left;
+ display : block;
+ padding : 0.5ex;
+ height : 2.5em;
+}
+
+div#tasklist {
+ width : 100%;
+ border : 1px solid #000000;
+ color : #000000;
+ background-color : #e6eef6;
+}
+
+/* The table listing tasks on the main page */
+div#tasklist table {
+ width : 100%;
+ border-spacing : 0px;
+ border-collapse : collapse;
+}
+
+div#tasklist table th {
+ text-align : left;
+ padding : 2px 1em 2px 2px;
+ border-bottom : 1px solid #cccccc;
+}
+
+div#tasklist table td {
+ border-bottom : 1px solid #CCC;
+ padding : 2px 1ex 2px 2px;
+}
+
+div#tasklist table td.taskid, div#tasklist table th.taskid {
+ text-align : center;
+ padding : 2px 1ex;
+}
+
+div#tasklist table td.taskdate {
+ text-align : left;
+ white-space : nowrap;
+}
+
+div#tasklist table td.progress {
+ vertical-align : middle;
+ text-align : center;
+}
+
+table#pagenumbers {
+ width : 100%;
+}
+
+table#pagenumbers td#taskrange {
+ padding : 0px 0px 0px 5px;
+ }
+
+table#pagenumbers td#numbers {
+ padding : 0px 5px 0px 0px;
+ text-align : right;
+}
+
+/* table.list is any table holding lists like resolutions, ... */
+table.list th, table.list td {
+ padding-right : 2em;
+}
+
+table.list label, p#showtask label, p.admin label, form#formaddrelatedtask label {
+ display : inline;
+}
+
+/* Area containing all details to a given task */
+div#taskdetails {
+ margin : 2em 0px 1em 0px;
+ background-color : #e6eef6;
+ border : 1px solid #000000;
+}
+
+div#taskdetails h2 {
+ font-size : 100%;
+ padding : 0.3ex 1ex;
+ font-weight : normal;
+}
+
+table.taskdetails td {
+}
+
+/* Task details are listed within a table */
+div#taskdetails table {
+ width : 90%;
+}
+
+div#taskdetails table th {
+ text-align : left;
+ font-weight : bold;
+}
+
+/* div#content is a generic container for anything but the title and
+ the footer paragraph */
+div#content {
+/* border : 2px solid #948d94;*/
+ margin : 5px;
+ padding : 5px;
+/* color : #000000;
+ background-color : #ffffff;
+ z-index : -1;*/
+}
+
+div#content div, div#content fieldset {
+/* -moz-border-radius : 13px; */
+}
+
+div#content div h2 {
+/* -moz-border-radius : 15px; */
+}
+
+/* Powered by Flyspray */
+p#footer {
+ margin : 0em 0em;
+ padding : 5px;
+ background-color : #47617b;
+ border : 3px double white;
+ color : #ffffff;
+ text-align : center;
+ margin-top : 15px;
+ clear : both;
+}
+
+p#footer a:link {
+ color : #ffffff;
+ background-color : transparent;
+}
+
+p#footer a:visited {
+ color : #ffffff;
+ background-color : transparent;
+}
+
+p#footer a:hover {
+ color : #ffffff;
+ background-color : transparent;
+}
+
+/* used solely for several browsers do not support [type="submit"]
+ selectors. These are buttons and buttons only used by the admin */
+input.adminbutton, input.mainbutton, button {
+ background-color : #838ab5;
+ color : #ffffff;
+ background-image : url(button.png);
+ background-repeat : repeat-x;
+ border : 1px ridge #000000;
+ font-weight : bold;
+}
+
+input.adminbutton:hover, input.mainbutton:hover, button:hover {
+ cursor : pointer;
+}
+
+/* div.redirectmessage is used in modify.inc.php when you change things and are redirected
+ to the index or details page */
+div.redirectmessage {
+ border : 1px solid #CCC;
+ background-color : #e6eef6;
+ padding : 1ex;
+ text-align : center;
+}
+
+/* form#registernewuser, form#chgpassword, form#newgroup are used in
+ the popup windows */
+form#chgpassword h1, form#registernewuser h1, form#newgroup h1 {
+ font-size : 110%;
+ margin : 2px;
+ padding : 0px;
+}
+
+/* .buttons used for table cells containing buttons */
+.buttons {
+ text-align : center;
+}
+
+form#registernewuser strong, form#newgroup strong {
+ color : red;
+}
+
+
+
+p#tabs {
+ margin : 0px;
+ padding : 0px;
+}
+
+p#tabs a {
+ background-image : url("tab-notactive.png");
+ background-repeat : no-repeat;
+ background-position : top left;
+ background-color : #cad0d7;
+ border-right : 1px solid #93989D;
+}
+
+p#tabs a.tabactive {
+ background-image : url("tab-active.png");
+ background-repeat : no-repeat;
+ background-position : top left;
+ background-color : #e6eef6;
+ border-right : 1px solid #CCC;
+ padding-bottom : 2px;
+}
+
+div.tabentries {
+ background-color : #e6eef6;
+ margin : 0px 0px 1em 0px;
+ border : 1px solid #CCC;
+ min-height : 5em;
+}
+
+.tabentry {
+ margin : 2px 1em;
+ border-bottom : 1px solid #ccc;
+}
+
+/* This is the division that keeps the buttons to modify comments
+ (delete, edit) */
+div.modifycomment {
+ float: right;
+ width : 20em;
+ text-align : right;
+}
+
+div.modifycomment p {
+ display : inline;
+ margin : 0px;
+ padding : 0px;
+}
+
+/* The tabs containing the links to comments, attachments, ...
+ in details.php */
+p#tabs a {
+ margin : 2px 0px;
+ padding : 0px 1em;
+ white-space : nowrap;
+}
+
+/* separators between the links in the tabs */
+p#tabs small {
+ display : none;
+}
+
+/* p.unregistered holds links to open new task when you're unregistered */
+p.unregistered {
+ margin : 0px;
+ padding : 0px;
+}
+
+/* Some generic classes; severity classes are used for colour
+ indication of severities
+ IE can't do hover on anything but A elements, so there is a
+ script in /js/ie_hover.js that fixes this with
+ javascript. That javascript only checks background-color and
+ color. If you want to change other properties during the hover
+ you'll have to adjust the javascript
+ */
+.severity1 {
+ background-color : #fff5dd;
+ color : #000000;
+ height : 1%;
+}
+
+.severity1:hover {
+ background-color : #ffe9b4;
+ color : #000000;
+ cursor : pointer;
+}
+
+.severity2 {
+ background-color : #ecdbb7;
+ color : #000000;
+ height : 1%;
+}
+
+.severity2:hover {
+ background-color : #efca80;
+ color : #000000;
+ cursor : pointer;
+}
+
+.severity3 {
+ background-color : #ecd0b7;
+ color : #000000;
+ height : 1%;
+}
+
+.severity3:hover {
+ background-color : #edb98a;
+ color : #000000;
+ cursor : pointer;
+}
+
+.severity4 {
+ background-color : #ffd5d1;
+ color : #000000;
+ height : 1%;
+}
+
+.severity4:hover {
+ background-color : #ffb2ac;
+ color : #000000;
+ cursor : pointer;
+}
+
+.severity5 {
+ background-color : #f3a29b;
+ color : #000000;
+ height : 1%;
+}
+
+.severity5:hover {
+ background-color : #f3867e;
+ color : #000000;
+ cursor : pointer;
+}
+
+/* .fineprint is merely used for the details about when a task has
+ been created and changed (in the details pages) */
+div#fineprint {
+ font-size : smaller;
+ border-bottom : 1px solid #cccccc;
+ margin : 0px 0px 10px 5px;
+ padding-bottom : 10px;
+ height : 1%;
+}
+
+table.history
+{
+ width : 100%;
+ margin : 1em 0px 1em 0px;
+ padding : 0px 1em 0px 1em;
+ background-color : #e6eef6;
+ color : black;
+ font-family : Helvetica, Verdana, Sans-Serif;
+}
+
+table.history td {
+ border-bottom : 1px solid #ccc;
+ border-left : 1px solid #ccc;
+ padding-left : 5px;
+}
+
+table.history td.taskid {
+ text-align : center;
+ padding : 2px 1ex;
+}
+
+div#intromessage {
+ margin : 1px;
+ margin-top : -20px;
+ margin-bottom : 10px;
+}
+
+map#formselecttasks {
+ margin : 0em 0px 0em 0px;
+}
+
+a.closedtasklink {
+ text-decoration: line-through;
+}
+
+div#taskfields1 {
+ float: left;
+ width: 49%;
+ border-right: 1px solid #cccccc;
+ margin-bottom: 8px;
+}
+
+div#taskfields2 {
+ float: left;
+ width: 49%;
+ margin-bottom: 8px;
+}
+
+div#taskfields1 table td {
+ width: 50%;
+}
+
+div#taskfields2 table td {
+ width: 50%;
+}
+
+div#taskdetailsfull {
+ clear : both;
+ width : 99%;
+ margin-top : 15px;
+ padding : 15px 0px 15px 8px;
+ border-top : 1px solid #cccccc;
+ border-bottom : 1px solid #cccccc;
+ text-align : left;
+}
+
+div#taskdetailsfull label {
+ text-align : left;
+}
+
+div#deps {
+ padding : 8px;
+ width : 98%;
+ border-bottom : 1px solid #cccccc;
+ min-height : 50px;
+ float : left;
+}
+
+div#taskdeps {
+ float: left;
+ width: 45%;
+ margin-bottom: 8px;
+}
+
+div#taskblocks {
+ float: left;
+ width: 50%;
+}
+
+div#actionbuttons {
+ clear : both;
+ padding : 5px;
+}
+
+div#actionbuttons a {
+ background-image : url(button.png);
+ background-repeat : repeat-x;
+ color : #ffffff;
+ background-color : transparent;
+ border : 1px solid #000000;
+ margin : 0px 3px 0px 3px;
+ /* padding values: top, right, bottom, left */
+ padding : 2px 5px 2px 5px;
+}
+
+div#actionbuttons a#hideclosetask {
+ position : absolute;
+ top : 3px;
+ right : 3px;
+ width : 16px;
+ height : 16px;
+ background-image : url(cancel.png);
+ background-repeat : no-repeat;
+ color : #000000;
+ background-color : transparent;
+ border : none;
+}
+
+div#actionbuttons a#hideclosetask:hover {
+ position : absolute;
+ top : 3px;
+ right : 3px;
+ width : 16px;
+ height : 16px;
+ background-image : url(cancel-over.png);
+ background-repeat : no-repeat;
+ color : #000000;
+ background-color : transparent;
+ border : none;
+}
+
+div#massopsactions {
+ padding : 0px 0px 0px 3px;
+}
+
+div#closeform {
+ visibility : hidden;
+ position : absolute;
+ background-color : #e6eef6;
+ color : #000000;
+ border : 3px ridge #000000;
+ padding : 5px 30px 5px 5px;
+ margin-top : 5px;
+ display : block;
+ width : 300px;
+ height : auto;
+}
+
+div#closeform textarea {
+ width : 100%;
+ height : 100px;
+}
+
+div.denyform {
+ visibility : hidden;
+ position : absolute;
+ right : 12px;
+ background-color : #e6eef6;
+ color : #000000;
+ border : 3px ridge #000000;
+ padding : 5px 30px 5px 5px;
+ margin-top : 5px;
+ display : block;
+ width : 300px;
+ height : auto;
+}
+
+div#denyform textarea {
+ width : 100%;
+ height : 100px;
+}
+
+fieldset.admin {
+ margin-top : 15px;
+ background-color : #e6eef6;
+ color : #000000;
+ border : 1px solid #000000;
+}
+
+fieldset.admin legend {
+ border-bottom : 1px solid #000000;
+ border-right : 1px solid #000000;
+ padding : 2px;
+ font : 120% Helvetica, Verdana, sans-serif;
+ margin : 5px;
+ background-color : #f5f9fd;
+ color : #000000;
+}
+
+div#errorbar {
+ width : 100%;
+ height : 20px;
+ color : yellow;
+ background-color : red;
+ font-weight : bold;
+ position : fixed;
+ bottom : 0px;
+ background-image : url(frown.png);
+ background-repeat : no-repeat;
+ background-position : 5px 0px;
+ padding-left : 30px;
+}
+
+div#successbar {
+ width : 100%;
+ height : 20px;
+ color : #ffffff;
+ background-color : green;
+ font-weight : bold;
+ position : fixed;
+ bottom : 0px;
+ background-image : url(smile.png);
+ background-repeat : no-repeat;
+ background-position : 5px 0px;
+ padding-left : 30px;
+}
+
+div#toolboxmenu {
+ width : auto;
+ float : left;
+ margin-right : 25px;
+ margin-top : 15px;
+}
+
+div#toolboxmenu small {
+ display : none;
+}
+
+div#toolboxmenu a {
+ display : block;
+ border : 1px solid #000000;
+ padding-top : 1em;
+ padding-bottom : 1em;
+ width : 120px;
+ text-align : center;
+}
+
+div#toolboxmenu a:hover {
+ color : #6395c8;
+ background-color : #d7e9ff;
+}
+
+div#toolbox {
+ margin-left : 150px;
+ min-height : 350px;
+}
+
+a.grouptitle {
+ font-size : 16px;
+}
+
+/* The new tabs stuff */
+/* colors */
+#submenu a, div.tab { color: #000000; background-color: #e6eef6; }
+
+#submenu a.active {
+ color : #000000;
+ border-bottom-color : #cdc;
+}
+
+#submenu a:hover {
+ color : #000000;
+}
+
+#submenu a { color: #999;text-decoration: none; }
+#submenu a.active { z-index:5;}
+
+/* margins */
+#submenu, #submenu * { margin: 0; padding: 0; }
+#submenu a, div.tab { border: solid 1px black; }
+#submenu a { margin: auto auto -1px 1ex; padding: 2px 1ex; }
+* html #submenu { margin-bottom: -1em; }
+div.tab { margin: 0; padding: 1ex; padding-bottom: 1cm; margin-right: 1ex; margin-bottom: 10px;}
+
+/* flow */
+#submenu li { display: inline; width: 0; height: 0; }
+#submenu a { display: block; float: left; }
+div.tab h2 { display: none; }
+div.tab { clear: left; }
+* html .tab div.clear { clear: none; height: 14em; }
+
+div#permslink {
+ position : absolute;
+ top : 5px;
+ right : 5px;
+ color : #ffffff;
+ background-color : transparent;
+}
+
+div#permslink a {
+ color : #ffffff;
+ background-color : transparent;
+}
+
+div#permissions {
+ visibility : hidden;
+ position : absolute;
+ top : 25px;
+ right : 5px;
+ padding : 5px;
+ margin-top : none;
+ overflow : auto;
+ z-index : 5;
+}
+
+div#permissions table {
+ color : #000000;
+ background-color : #ffffff;
+ border : 1px dotted #000000;
+}
+
+div#permissions table td {
+ border : 0px;
+}
+
+div#fileupload {
+ margin : 20px 0px 20px 0px;
+}
+
+span#pendingreq {
+ margin : 0px 0px 0px 9px;
+ display: : block;
+ clear : both;
+ font-size : 120%;
+ font-weight : bold;
+ float : right;
+ color : red;
+ background-color : yellow;
+}
+
+/* container for the next/previous links in the task details */
+span#navigation {
+ position : absolute;
+ right : 1em;
+}
+
+span#navigation a#next {
+ padding-right : 20px;
+ background-image : url(next.png);
+ background-repeat : no-repeat;
+ background-position : right;
+}
+
+span#navigation a#prev {
+ padding-left : 20px;
+ background-image : url(prev.png);
+ background-repeat : no-repeat;
+ background-position : left;
+}
+
+
+
+/* End of the @screen section */
+}
+
+@media print {
+p#menu {
+ display : none;
+}
+
+/* End of the @print section */
+}
diff --git a/setup/templates/administration.tpl b/setup/templates/administration.tpl
new file mode 100644
index 0000000..58909b0
--- /dev/null
+++ b/setup/templates/administration.tpl
@@ -0,0 +1,79 @@
+<div>
+<form action="index.php" method="post" name="database_form">
+ <?php echo $message; ?>
+ <h1><?= eL('administrationsetup') ?></h1>
+ <h2><?= eL('setupapplicationvalue') ?></h2>
+ <div class="installBlock">
+<script type="text/javascript">
+function ShowHidePassword(id) {
+ if(document.getElementById(id).type=="text") {
+ document.getElementById(id).type="password";
+ } else {
+ document.getElementById(id).type="text";
+ }
+}
+</script>
+
+ <p><?= L('adminsetuptip1') ?></p>
+ <p><?= L('adminsetuptip2') ?></p>
+ <p><?= L('adminsetuptip3') ?></p>
+
+ <table class="formBlock">
+ <tr>
+ <td style="text-align:right"><?= eL('adminusername') ?></td>
+ <td style="text-align:left"><input class="inputbox" type="text" name="admin_username" value="<?php echo $admin_username; ?>" required="required" size="30" /></td>
+ <td></td>
+ </tr>
+ <tr>
+ <td style="text-align:right"><?= eL('adminrealname') ?></td>
+ <td style="text-align:left"><input class="inputbox" type="text" name="admin_realname" value="<?php echo $admin_realname; ?>" size="30" /></td>
+ <td></td>
+ </tr>
+ <tr>
+ <td style="text-align:right"><?= eL('adminemail') ?></td>
+ <td style="text-align:left"><input class="inputbox" type="text" name="admin_email" value="<?php echo $admin_email; ?>" required="required" size="30" /></td>
+ <td></td>
+ </tr>
+ <tr>
+ <td style="text-align:right"><?= eL('adminxmpp') ?></td>
+ <td style="text-align:left"><input class="inputbox" type="text" name="admin_xmpp" value="<?php echo $admin_xmpp; ?>" size="30" /></td>
+ <td></td>
+ </tr>
+ <tr>
+ <td style="text-align:right"><?= eL('adminpassword') ?></td>
+ <td style="text-align:left"><input class="inputbox" type="password" name="admin_password" id="admin_password" value="<?php echo $admin_password; ?>" required="required" size="30" /></td>
+ <td style="text-align:left"><label for="showpassword"><?= eL('showpassword') ?></label><input type="checkbox" onclick="ShowHidePassword('admin_password')" id="showpassword"></td>
+ </tr>
+ <tr>
+ <td style="text-align:right"><?= eL('syntax') ?></td>
+ <td style="text-align:left">
+ <select name="syntax_plugin">
+ <option value="dokuwiki">Text/Dokuwiki</option>
+ <option value="none">HTML/none</option>
+ <option value="html">HTML/CKEditor</option>
+ </select>
+ </td>
+ <td style="text-align:left"><?= L('syntaxtext') ?></td>
+ </tr>
+ <?php if ($daemonise): ?>
+ <tr>
+ <td style="text-align:right" title="<?= eL('scheduletitle') ?>"><?= eL('enablescheduling') ?></td>
+ <td style="text-align:center"><?php echo $daemonise; ?></td>
+ </tr>
+ <?php endif; ?>
+ </table>
+
+ <input type="hidden" name="db_type" value="<?php echo Filters::noXSS($db_type); ?>" />
+ <input type="hidden" name="db_hostname" value="<?php echo Filters::noXSS($db_hostname); ?>" />
+ <input type="hidden" name="db_username" value="<?php echo Filters::noXSS($db_username); ?>" />
+ <input type="hidden" name="db_password" value="<?php echo Filters::noXSS($db_password); ?>" />
+ <input type="hidden" name="db_name" value="<?php echo Filters::noXSS($db_name); ?>" />
+ <input type="hidden" name="db_prefix" value="<?php echo Filters::noXSS($db_prefix); ?>" />
+
+ <p><?= eL('proceedtofinalsetuptext') ?></p>
+ <input type="hidden" name="action" value="complete" />
+ <button class="button" type="submit" name="next" value="<?= eL('next') ?> >>" ><?= eL('proceedtofinalsetup') ?></button>
+
+ </div>
+</form>
+</div>
diff --git a/setup/templates/complete_install.tpl b/setup/templates/complete_install.tpl
new file mode 100644
index 0000000..2def1e6
--- /dev/null
+++ b/setup/templates/complete_install.tpl
@@ -0,0 +1,50 @@
+<div>
+<form action="<?php echo Filters::noXSS($site_index); ?><?php echo Filters::noXSS($complete_action); ?>" method="post" name="database_form">
+ <h1><?php echo Filters::noXSS(L('installstatus')); ?></h1>
+ <h2><?php echo Filters::noXSS(L('congratulations')); ?></h2>
+ <div class="installBlock">
+ <p class="error"><?php echo Filters::noXSS(L('removesetupdirectory')); ?></p>
+ <?php if(!$config_writeable): ?>
+ <table class="formBlock">
+ <tr>
+ <td>
+ The configuration file is not writeable. You will have to upload the following
+ code manually. Click in the textarea to highlight all of the code. Copy and
+ paste the contents into the flyspray.conf.php file available in the base of
+ <?php echo Filters::noXSS($product_name); ?> installation.
+ </td>
+ </tr>
+ <tr>
+ <td align="center">
+ <textarea class="inputbox" rows="10" cols="38" name="configcode" onclick="javascript:this.form.configcode.focus();this.form.configcode.select();" ><?php echo htmlspecialchars($config_text); ?></textarea>
+ </td>
+ </tr>
+ </table>
+ <h3>flyspray.conf.php NOT writeable</h3>
+ <p>
+ To complete setup, copy and paste the contents of the textarea box into flyspray.conf.php
+ This file resides in the base of your <?php echo Filters::noXSS($product_name); ?> installation.
+ </p>
+ <?php endif; ?>
+ <?php
+ if ($admin_username && $admin_password): ?>
+ <h3>Administration Login Details</h3>
+ <p>
+ <strong>Username: <?php echo Filters::noXSS($admin_username); ?></strong><br />
+ <strong>Password: <?php echo Filters::noXSS($admin_password); ?></strong>
+ </p>
+ <?php endif; ?>
+
+ <?php if ($admin_username && $admin_password): ?>
+ <input type="hidden" name="return_to" value="./" />
+ <input type="hidden" name="do" value="authenticate" />
+ <input type="hidden" name="user_name" value="<?php echo Filters::noXSS($admin_username); ?>" />
+ <input type="hidden" name="password" value="<?php echo Filters::noXSS($admin_password); ?>" />
+ <?php endif; ?>
+ <p><?php echo Filters::noXSS(L('proceedtoindex')); ?></p>
+ <input type="hidden" name="remember_login" value="1" />
+ <button class="button" type="submit" name="next" value="next"><?php echo Filters::noXSS(L('viewsite')); ?></button>
+
+ </div>
+</form>
+</div>
diff --git a/setup/templates/database.tpl b/setup/templates/database.tpl
new file mode 100644
index 0000000..f5e29a8
--- /dev/null
+++ b/setup/templates/database.tpl
@@ -0,0 +1,47 @@
+<div>
+<form action="index.php" method="post" name="database_form">
+ <?php echo $message; ?>
+
+ <h1><?= eL('databasesetup') ?></h1>
+ <h2><?= eL('databaseconfiguration') ?><?php echo Filters::noXSS($version); ?></h2>
+ <div class="installBlock">
+ <table class="formBlock" style="width:auto">
+ <tr>
+ <td><?= eL('databasehostname') ?></td>
+ <td align="left"><input required="required" type="text" name="db_hostname" value="<?php echo Filters::noXSS($db_hostname); ?>" /></td>
+ <td><?= L('databasehostnamehint') ?></td>
+ </tr>
+ <tr>
+ <td><?= eL('databasetype') ?></td>
+ <td><select name="db_type">
+ <?php echo tpl_options(array_combine(array_map(create_function('$x', 'return $x[2];'), $databases), array_keys($databases)), $db_type); ?>
+ </select>
+ </td>
+ <td><?= L('databasetypehint') ?></td>
+ </tr>
+ <tr>
+ <td><?= eL('databasename') ?></td>
+ <td align="left"><input required="required" type="text" name="db_name" value="<?php echo Filters::noXSS($db_name); ?>" /></td>
+ <td><?= L('databasenamehint') ?></td>
+ </tr>
+ <tr>
+ <td><?= eL('databaseusername') ?></td>
+ <td align="left"><input required="required" type="text" name="db_username" value="<?php echo Filters::noXSS($db_username); ?>" /></td>
+ <td rowspan="2"><?= L('databaseusernamehint') ?></td>
+ </tr>
+ <tr>
+ <td><?= eL('databasepassword') ?></td>
+ <td align="left"><input type="password" name="db_password" value="<?php echo Filters::noXSS($db_password); ?>" /></td>
+ </tr>
+ <tr>
+ <td><?= eL('tableprefix') ?></td>
+ <td align="left"><input type="text" maxlength="10" name="db_prefix" value="<?php echo Filters::noXSS($db_prefix); ?>" /></td>
+ <td><?= L('tableprefixhint') ?></td>
+ </tr>
+ </table>
+
+ <input type="hidden" name="action" value="administration" />
+ <button class="button" type="submit" name="next" value="next"><?= eL('proceedtoadmin') ?></button>
+ </div>
+</form>
+</div>
diff --git a/setup/templates/pre_install.tpl b/setup/templates/pre_install.tpl
new file mode 100644
index 0000000..3c65e43
--- /dev/null
+++ b/setup/templates/pre_install.tpl
@@ -0,0 +1,124 @@
+<div>
+ <?php echo Filters::noXSS($message); ?>
+
+ <h1><?php echo Filters::noXSS(L('preinstallcheck')); ?></h1>
+ <h2><?php echo Filters::noXSS(L('libcheck')); ?></h2>
+ <div class="installBlock">
+ <p><?php echo L('libchecktext'); ?></p>
+ <table class="formBlock">
+ <tr>
+ <td class="heading"><?php echo Filters::noXSS(L('library')); ?></td>
+ <td class="heading"><?php echo Filters::noXSS(L('status')); ?></td>
+ <td class="heading">&nbsp;</td>
+ </tr>
+ <tr>
+ <td>PHP <?php echo PHP_VERSION; ?> >= <?php echo Filters::noXSS($required_php); ?></td>
+ <td align="left"><b><?php echo $php_output; ?></b></td>
+ <td>&nbsp;</td>
+ </tr>
+ <tr>
+ <td>XML Extension</td>
+ <td align="left"><b><?php echo Setup::ReturnStatus($xmlStatus); ?></b></td>
+ <td>&nbsp;</td>
+ </tr>
+ <tr>
+ <td>cURL Library</td>
+ <td align="left"><b><?php echo Setup::ReturnStatus(extension_loaded('curl'), 'yes'); ?></b></td>
+ <td>required if you want allow Oauth2 authentications</td>
+ </tr>
+ <tr>
+ <td>GD Library</td>
+ <td align="left"><b><?php echo Setup::ReturnStatus(extension_loaded('gd'), 'yes'); ?></b></td>
+ <td>&nbsp;</td>
+ </tr>
+ <tr>
+ <td>Exif Library</td>
+ <td align="left"><b><?php echo Setup::ReturnStatus(extension_loaded('exif'), 'yes'); ?></b></td>
+ <td>&nbsp;</td>
+ </tr>
+ <tr>
+ <td>SAPI (<?php echo Filters::noXSS(php_sapi_name()); ?>)</td>
+ <td align="left"><b><?php echo Setup::ReturnStatus($sapiStatus, 'support'); ?></b></td>
+ <td>&nbsp;</td>
+ </tr>
+ <tr>
+ <td class="heading"><?php echo Filters::noXSS(L('database')); ?></td>
+ <td class="heading"><?php echo Filters::noXSS(L('inphp')); ?></td>
+ <td class="heading" style="text-align:center"><?php echo Filters::noXSS($product_name); ?></td>
+ </tr>
+ <?php echo $database_output; ?>
+ </table>
+
+ <?php if (!$sapiStatus): ?>
+ <p><strong>CGI server API is not supported</strong>. Consider upgrading to FastCGI, otherwise you have to add
+ <code>force_baseurl = "http://yourflyspray/"</code> manually to flyspray.conf.php after setup.
+ </p>
+ <?php endif; ?>
+ </div>
+
+ <h2><?php echo Filters::noXSS(L('recsettings')); ?></h2>
+ <div class="installBlock">
+ <p><?php echo Filters::noXSS(L('recsettingstext1')); ?></p>
+ <p><?php echo Filters::noXSS(L('recsettingstext2')); ?></p>
+ <table class="formBlock">
+ <tr>
+ <td class="heading"><?php echo Filters::noXSS(L('directive')); ?></td>
+ <td class="heading"><?php echo Filters::noXSS(L('recommended')); ?></td>
+ <td class="heading"><?php echo Filters::noXSS(L('actual')); ?></td>
+ </tr>
+ <?php echo $php_settings; ?>
+ </table>
+ </div>
+
+ <h2><?php echo Filters::noXSS(L('dirandfileperms')); ?></h2>
+ <div class="installBlock">
+ <p><?php echo Filters::noXSS(L('dirandfilepermstext')); ?></p>
+ <table class="formBlock">
+ <tr>
+ <td valign="top">../flyspray.conf.php</td>
+ <td align="left"><b><?php echo $config_output; ?></b></td>
+ <td>&nbsp;</td>
+ </tr>
+ <tr>
+ <td valign="top">../cache</td>
+ <td align="left"><b><?php echo $cache_output; ?></b></td>
+ <td>&nbsp;</td>
+ </tr>
+ <tr>
+ <td valign="top">../attachments</td>
+ <td align="left"><b><?php echo $att_output; ?></b></td>
+ <td>&nbsp;</td>
+ </tr>
+ <tr>
+ <td valign="top">../avatars</td>
+ <td align="left"><b><?php echo $ava_output; ?></b></td>
+ <td>&nbsp;</td>
+ </tr>
+ </table>
+
+ <?php if (!$config_status): ?>
+ <p>
+ The installer has detected that the <strong>flyspray.conf.php</strong> file is not
+ writeable. Please make it writeable by the web-server user or world writeable to
+ proceed with the setup. Alternatively if you wish to proceed, the installer will
+ make available the contents of the configuration file at the end of the setup. You
+ will then have to manually copy and paste the contents into the configuration file
+ located at <strong><?php echo APPLICATION_PATH . DIRECTORY_SEPARATOR . 'flyspray.conf.php'; ?></strong>.
+ </p>
+ <?php endif; ?>
+
+ <?php if (!$status) { ?>
+ <p>
+ You seem to have problems with the Pre-install configuration. Once you have fixed the
+ problem, please refresh the page to be able to proceed to the next stage of
+ <?php echo Filters::noXSS($product_name); ?> setup.
+ </p>
+ <?php }else { ?>
+ <p><?php echo Filters::noXSS(L('proceedtodbsetuptext')); ?></p>
+ <?php } ?>
+ <form action="index.php" method="post" name="adminForm">
+ <input type="hidden" name="action" value="database" />
+ <button name="next" type="submit" class="button" value="next" <?php echo Filters::noXSS(tpl_disableif(!$status)); ?> ><?php echo Filters::noXSS(L('proceedtodbsetup')); ?></button>
+ </form>
+ </div>
+</div>
diff --git a/setup/templates/structure.tpl b/setup/templates/structure.tpl
new file mode 100644
index 0000000..84a7491
--- /dev/null
+++ b/setup/templates/structure.tpl
@@ -0,0 +1,56 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<title><?php echo Filters::noXSS($title . ' ' . $product_name); ?></title>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<link rel="stylesheet" href="styles/setup.css" type="text/css" media="screen" />
+<?php echo $headers; ?>
+</head>
+<body>
+<div id="header">
+ <div id="logo">
+ <h1><a href="<?php echo Filters::noXSS($index); ?>" title="Flyspray - <?= eL('slogan') ?>"><?= eL('slogan') ?></a></h1>
+ </div><!-- End of logo -->
+</div><!-- End of header -->
+<div id="content">
+ <div id="stepbar" title="<?= eL('progress') ?>">
+ <!-- <div><?= eL('progress') ?></div> -->
+ <div class="done">3rd party libs</div>
+ <div<?php
+ if(!isset($_POST['action'])){
+ echo ' class="step-on"';
+ } elseif( $_POST['action'] == 'database' || $_POST['action'] == 'administration' || $_POST['action'] == 'complete' ){
+ echo ' class="done"';
+ } ?>><?= eL('preinstallcheck') ?></div>
+ <div<?php
+ if(isset($_POST['action'])){
+ if( $_POST['action'] == 'database' ){
+ echo ' class="step-on"';
+ } elseif( $_POST['action'] == 'administration' || $_POST['action'] == 'complete' ){
+ echo ' class="done"';
+ }
+ }
+ ?>><?= eL('databasesetup') ?></div>
+ <div<?php
+ if(isset($_POST['action'])){
+ if($_POST['action'] == 'administration'){
+ echo ' class="step-on"';
+ } elseif($_POST['action'] == 'complete'){
+ echo ' class="done"';
+ }
+ } ?>><?= eL('administration') ?></div>
+ <div<?php echo (isset($_POST['action']) && ($_POST['action'] == 'complete')) ? ' class="step-on"' : ''; ?>><?php echo Filters::noXSS(L('installflyspray')); ?></div>
+ </div>
+ <?php echo $body; ?>
+</div><!-- End of content -->
+<div id="footer">
+ <ul id="docs">
+ <li><a href="https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html" title="<?= eL('lgpllicense') ?>" target="_blank"><?= eL('lgpllicense') ?></a></li>
+ <li><a href="https://www.flyspray.org/manual/" title="<?= eL('installationguide') ?>" target="_blank"><?= eL('installationguide') ?></a></li>
+ </ul>
+ <p>Flyspray <?php echo Filters::noXSS($version); ?><br />
+ Copyright 2004-<?php echo Filters::noXSS(date('Y')); ?> &copy; The Flyspray team. All rights reserved.
+ </p>
+</div><!-- End of footer -->
+</body>
+</html>
diff --git a/setup/templates/upgrade.tpl b/setup/templates/upgrade.tpl
new file mode 100644
index 0000000..68e1619
--- /dev/null
+++ b/setup/templates/upgrade.tpl
@@ -0,0 +1,76 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<title><?php echo Filters::noXSS($title); ?> Flyspray</title>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<link rel="stylesheet" href="styles/setup.css" type="text/css" media="screen" />
+</head>
+<body>
+<div id="header">
+ <div id="logo">
+ <h1><a href="<?php echo Filters::noXSS($index); ?>" title="Flyspray - The bug Killer!"><?php echo L('upgrade'); ?></a></h1>
+ </div><!-- End of logo -->
+</div><!-- End of header -->
+<div id="content">
+<form action="upgrade.php" method="post" onsubmit="document.getElementById('upgradebutton').disabled = true;return true;" >
+ <input type="hidden" name="upgrade" value="1" />
+ <div class="install">
+ <h2><?php echo L('preconditionchecks'); ?></h2>
+ <p><?php echo sprintf(L('versioncompare'), $installed_version, $short_version); ?></p>
+ <p><?php echo L('writeaccessconf'); ?></p>
+ <div class="installBlock">
+ <table class="formBlock">
+ <tr>
+ <td valign="top">../<?php echo Filters::noXSS(basename(CONFIG_PATH)); ?></td>
+ <td align="left"><b><?php if ($checks['config_writable']): ?><span class="green">writeable</span><?php else: ?><span class="red">not writeable</span><?php endif; ?></b></td>
+ </tr>
+ <tr>
+ <td valign="top">Database connection</td>
+ <td align="left"><b><?php if ($checks['db_connect']): ?><span class="green">OK</span><?php else: ?><span class="red">Failed</span><?php endif; ?></b></td>
+ </tr>
+ </table>
+ </div>
+<?php if (!$upgrade_possible): ?>
+ <p style="clear:both">Apparently, an upgrade is not possible. <?php echo Filters::noXSS($todo); ?></p>
+ <p style="text-align:center"><a class="button" href="../">Back to Home</a></p>
+<?php else: ?>
+ <p><?php echo L('upgradepossible'); ?></p>
+ <h2><?php echo L('precautions'); ?></h2>
+ <p><?php echo L('precautionbackup'); ?></p>
+
+ <?php if (isset($upgrade_options)): ?>
+ <h2>Upgrade options</h2>
+ <p><?php echo $upgrade_options; ?></p>
+ <?php endif; ?>
+
+ <?php if ($ask_for_conversion): ?>
+ <h2><?php echo L('explainwhatandwhyheader'); ?></h2>
+ <p><?php echo L('explainwhatandwhycontent'); ?></p>
+ <p><input name="yes_please_do_convert" type="checkbox"/><?php echo eL('yes'); ?>
+ <input name="no_please_do_not_convert" type="checkbox"/><?php echo eL('no'); ?></p>
+ <?php endif; ?>
+
+ <h2><?php echo L('performupgrade'); ?></h2>
+ <p><input name="upgrade" id="upgradebutton" class="button" value="<?php echo eL('performupgrade'); ?>" type="submit" /></p>
+ <?php if (isset($done)): ?>
+ <div class="green"><?php echo join('<br />',$upgradelog); ?></div>
+ <p>If all went fine:</p>
+ <ol>
+ <li>Delete setup directory or restrict access to this directory by a htaccess rule.</li>
+ <li><a href="../" class="button" style="padding:4px;background-color:#fff;border-radius:3px;border:1px solid #000;display:inline-block">Back to Overview</a></li>
+ </ol>
+ <?php else: ?>
+ <p>Info: This may take a while depending on the upgrade type and your database size: from a few seconds up to doing a coffee break.</p>
+ <p>We do not get upgrade progress feedback while the upgrading process is running, but if it takes longer it can be a sign of problem.</p>
+ <?php endif; ?>
+<?php endif; ?>
+ </div><!-- End of install -->
+</form>
+</div><!-- End of content -->
+<div id="footer">
+ <p>Flyspray <?php echo Filters::noXSS($fs->version); ?><br />
+ Copyright 2004-<?php echo Filters::noXSS(date('Y')); ?> &copy; The Flyspray team. All rights reserved.
+ </p>
+</div><!-- End of footer -->
+</body>
+</html>
diff --git a/setup/upgrade.php b/setup/upgrade.php
new file mode 100644
index 0000000..46d108b
--- /dev/null
+++ b/setup/upgrade.php
@@ -0,0 +1,643 @@
+<?php
+// +----------------------------------------------------------------------
+// | PHP Source
+// +----------------------------------------------------------------------
+// | Copyright (C) 2006 by Cristian Rodriguez R <judas.iscariote@flyspray.org>
+// | Copyright (C) 2007 by Florian Florian Schmitz <floele@flyspray.org>
+// +----------------------------------------------------------------------
+// |
+// | Copyright: See COPYING file that comes with this distribution
+// +----------------------------------------------------------------------
+//
+
+@set_time_limit(0);
+//do it fast damn it
+ini_set('memory_limit', '64M');
+
+// define basic stuff first.
+define('IN_FS', 1);
+define('BASEDIR', dirname(__FILE__));
+define('APPLICATION_PATH', dirname(BASEDIR));
+define('OBJECTS_PATH', APPLICATION_PATH . '/includes');
+require_once OBJECTS_PATH . '/class.flyspray.php';
+define('CONFIG_PATH', Flyspray::get_config_path(APPLICATION_PATH));
+
+define('TEMPLATE_FOLDER', BASEDIR . '/templates/');
+$conf = @parse_ini_file(CONFIG_PATH, true) or die('Cannot open config file at ' . CONFIG_PATH);
+
+$borked = str_replace( 'a', 'b', array( -1 => -1 ) );
+
+if(!isset($borked[-1])) {
+ die("Flyspray cannot run here, sorry :-( \n PHP 4.4.x/5.0.x is buggy on your 64-bit system; you must upgrade to PHP 5.1.x\n" .
+ "or higher. ABORTING. (http://bugs.php.net/bug.php?id=34879 for details)\n");
+}
+
+require_once OBJECTS_PATH . '/fix.inc.php';
+require_once OBJECTS_PATH . '/class.gpc.php';
+require_once OBJECTS_PATH . '/i18n.inc.php';
+
+# fake objects for load_translation()
+class user{var $infos=array();}; class project{var $id=0;};
+$user=new user; $proj=new project;
+load_translations();
+
+// Use composer autoloader
+require dirname(__DIR__) . '/vendor/autoload.php';
+
+// Initialise DB
+require_once dirname(__DIR__) . '/vendor/adodb/adodb-php/adodb.inc.php';
+require_once dirname(__DIR__) . '/vendor/adodb/adodb-php/adodb-xmlschema03.inc.php';
+
+$db = new Database;
+$db->dbOpenFast($conf['database']);
+
+$webdir = dirname(htmlspecialchars($_SERVER['PHP_SELF'], ENT_QUOTES, 'utf-8'));
+$baseurl = rtrim(Flyspray::absoluteURI($webdir),'/\\') . '/' ;
+
+// ---------------------------------------------------------------------
+// Application Web locations
+// ---------------------------------------------------------------------
+$fs = new Flyspray();
+
+define('APPLICATION_SETUP_INDEX', Flyspray::absoluteURI());
+define('UPGRADE_VERSION', Flyspray::base_version($fs->version));
+
+define('DOMAIN_HASH', md5($_SERVER['SERVER_NAME'] . (int) $_SERVER['SERVER_PORT']));
+define('CACHE_DIR', Flyspray::get_tmp_dir() . DIRECTORY_SEPARATOR . DOMAIN_HASH);
+
+// Get installed version
+$sql = $db->query('SELECT pref_value FROM {prefs} WHERE pref_name = ?', array('fs_ver'));
+$installed_version = $db->fetchOne($sql);
+
+$page = new Tpl;
+$page->assign('title', 'Upgrade ');
+$page->assign('short_version', UPGRADE_VERSION);
+
+if (!isset($conf['general']['syntax_plugin']) || !$conf['general']['syntax_plugin'] || $conf['general']['syntax_plugin'] == 'none') {
+ $page->assign('ask_for_conversion', true);
+} else {
+ $page->assign('ask_for_conversion', false);
+}
+
+//cleanup
+//the cache dir
+@rmdirr(sprintf('%s/cache/dokuwiki', APPLICATION_PATH));
+
+// ---------------------------------------------------------------------
+// Now the hard work
+// ---------------------------------------------------------------------
+
+// Find out which upgrades need to be run
+$folders = glob_compat(BASEDIR . '/upgrade/[0-9]*');
+usort($folders, 'version_compare'); // start with lowest version
+
+if (Post::val('upgrade')) {
+ $uplog=array();
+ $uplog[]="Start database transaction";
+ $db->dblink->StartTrans();
+ fix_duplicate_list_entries(true);
+ foreach ($folders as $folder) {
+ if (version_compare($installed_version, $folder, '<=')) {
+ $uplog[]="Start $installed_version to $folder";
+ $uplog[]= execute_upgrade_file($folder, $installed_version);
+ $installed_version = $folder;
+ $uplog[]="End $installed_version to $folder";
+ }
+ }
+
+ # maybe as Filter: $out=html2wiki($input, 'wikistyle'); and $out=wiki2html($input, 'wikistyle') ?
+ # No need for any filter, because dokuwiki format wouldn't be touched anyway. But maybe ask the user
+ # first and explain that html-formatting is now used instead of plain text on installations that didn't
+ # use dokuwiki format. Then, adding paragraph tags and line breaks might enhance readability.
+ // For testing, do not use yet, have to discuss this one with others.
+ if ((!isset($conf['general']['syntax_plugin']) || !$conf['general']['syntax_plugin'] || $conf['general']['syntax_plugin'] == 'none') && Post::val('yes_please_do_convert')) {
+ convert_old_entries('tasks', 'detailed_desc', 'task_id');
+ convert_old_entries('projects', 'intro_message', 'project_id');
+ convert_old_entries('projects', 'default_task', 'project_id');
+ convert_old_entries('comments', 'comment_text', 'comment_id');
+ $page->assign('conversion', true);
+ } else {
+ $page->assign('conversion', false);
+ }
+
+ // we should be done at this point
+ $db->query('UPDATE {prefs} SET pref_value = ? WHERE pref_name = ?', array($fs->version, 'fs_ver'));
+
+ // Fix the sequence in tasks table for PostgreSQL.
+ if ($db->dblink->dataProvider == 'postgres') {
+ $rslt = $db->query('SELECT MAX(task_id) FROM {tasks}');
+ $maxid = $db->fetchOne($rslt);
+ // The correct sequence should normally have a name containing at least both the table and column name in this format.
+ $rslt = $db->query('SELECT relname FROM pg_class WHERE NOT relname ~ \'pg_.*\' AND relname LIKE \'%' . $conf['database']['dbprefix'] . 'tasks_task_id%\' AND relkind = \'S\'');
+ if ($db->countRows($rslt) == 1) {
+ $seqname = $db->fetchOne($rslt);
+ $db->query('SELECT setval(?, ?)', array($seqname, $maxid));
+ }
+ }
+ // */
+ $db->dblink->completeTrans();
+ $installed_version = $fs->version;
+ $page->assign('done', true);
+ $page->assign('upgradelog', $uplog);
+}
+
+function execute_upgrade_file($folder, $installed_version)
+{
+ global $db, $page, $conf;
+ // At first the config file
+ $upgrade_path = BASEDIR . '/upgrade/' . $folder;
+ new ConfUpdater(CONFIG_PATH, $upgrade_path);
+
+ $upgrade_info = parse_ini_file($upgrade_path . '/upgrade.info', true);
+ // dev version upgrade?
+ if ($folder == Flyspray::base_version($installed_version)) {
+ $type = 'develupgrade';
+ } else {
+ $type = 'defaultupgrade';
+ }
+
+ // Next a mix of XML schema files and PHP upgrade scripts
+ if (!isset($upgrade_info[$type])) {
+ die('#1 Bad upgrade.info file.');
+ }
+
+ ksort($upgrade_info[$type]);
+ foreach ($upgrade_info[$type] as $file) {
+ if (substr($file, -4) == '.php') {
+ require_once $upgrade_path . '/' . $file;
+ }
+
+ if (substr($file, -4) == '.xml') {
+ $schema = new adoSchema($db->dblink);
+ $xml = file_get_contents($upgrade_path . '/' . $file);
+ // $xml = str_replace('<table name="', '<table name="' . $conf['database']['dbprefix'], $xml);
+ // Set the prefix for database objects ( before parsing)
+ $schema->setPrefix($conf['database']['dbprefix'], false);
+ $schema->parseSchemaString($xml);
+ $schema->executeSchema(null, true);
+ }
+ }
+
+ // Last but not least global prefs update
+ if (isset($upgrade_info['fsprefs'])) {
+ $sql = $db->query('SELECT pref_name FROM {prefs}');
+ $existing = $db->fetchCol($sql);
+ // Add what is missing
+ foreach ($upgrade_info['fsprefs'] as $name => $value) {
+ if (!in_array($name, $existing)) {
+ $db->query('INSERT INTO {prefs} (pref_name, pref_value) VALUES (?, ?)', array($name, $value));
+ }
+ }
+ // Delete what is too much
+ foreach ($existing as $name) {
+ if (!isset($upgrade_info['fsprefs'][$name])) {
+ $db->query('DELETE FROM {prefs} WHERE pref_name = ?', array($name));
+ }
+ }
+ }
+
+ $db->query('UPDATE {prefs} SET pref_value = ? WHERE pref_name = ?', array(basename($upgrade_path), 'fs_ver'));
+ #$page->assign('done', true);
+ return "Write ".basename($upgrade_path)." into table {prefs} fs_ver in database";
+}
+
+ /**
+ * Delete a file, or a folder and its contents
+ *
+ * @author Aidan Lister <aidan@php.net>
+ * @version 1.0.3
+ * @link http://aidanlister.com/repos/v/function.rmdirr.php
+ * @param string $dirname Directory to delete
+ * @return bool Returns TRUE on success, FALSE on failure
+ * @license Public Domain.
+ */
+
+ function rmdirr($dirname)
+ {
+ // Sanity check
+ if (!file_exists($dirname)) {
+ return false;
+ }
+
+ // Simple delete for a file
+ if (is_file($dirname) || is_link($dirname)) {
+ return unlink($dirname);
+ }
+
+ // Loop through the folder
+ $dir = dir($dirname);
+ while (false !== $entry = $dir->read()) {
+ // Skip pointers
+ if ($entry == '.' || $entry == '..') {
+ continue;
+ }
+ // Recurse
+ rmdirr($dirname . DIRECTORY_SEPARATOR . $entry);
+ }
+ // Clean up
+ $dir->close();
+ return rmdir($dirname);
+ }
+
+
+class ConfUpdater
+{
+ var $old_config = array();
+ var $new_config = array();
+
+ /**
+ * Reads the existing config file and updates it
+ * @param string $location
+ * @access public
+ * @return bool
+ */
+ function ConfUpdater($location, $upgrade_path)
+ {
+ if (!is_writable($location)) {
+ return false;
+ }
+
+ $this->old_config = parse_ini_file($location, true) or die('Aborting: Could not open config file at ' . $location);
+ $this->new_config = parse_ini_file($upgrade_path . '/flyspray.conf.php', true);
+ // Now we overwrite all values of the *default* file if there is one in the existing config
+ array_walk($this->new_config, array($this, '_merge_configs'));
+ // save custom attachment definitions
+ $this->new_config['attachments'] = $this->old_config['attachments'];
+ # first try to keep an existing oauth config on upgrades
+ $this->new_config['oauth'] = $this->old_config['oauth'];
+
+ $this->_write_config($location);
+ }
+
+ /**
+ * Callback function, merges config values
+ * @param array $settings
+ * @access private
+ * @return array
+ */
+ function _merge_configs(&$settings, $group)
+ {
+ foreach ($settings as $key => $value) {
+ if (isset($this->old_config[$group][$key])) {
+ $settings[$key] = $this->old_config[$group][$key];
+ }
+ // Upgrade to MySQLi if possible
+ if ($key == 'dbtype' && strtolower($settings[$key]) == 'mysql' && function_exists('mysqli_connect')) {
+
+ //mysqli is broken on 64bit systems in versions < 5.1 do not use it, tested, does not work.
+ if (php_uname('m') == 'x86_64' && version_compare(phpversion(), '5.1.0', '<')) {
+ continue;
+ }
+
+ $settings[$key] = 'mysqli';
+ }
+ //no matter what, change the randomization key on each upgrade as an extra security improvement.
+ if($key === 'cookiesalt') {
+ $settings[$key] = md5(uniqid(mt_rand(), true));
+ }
+ }
+ }
+
+ /**
+ * Writes the new config file to a given $location
+ * @param string $location
+ * @access private
+ */
+ function _write_config($location)
+ {
+ $new_config = "; <?php die( 'Do not access this page directly.' ); ?>\n\n";
+ foreach ($this->new_config as $group => $settings) {
+ $new_config .= "[{$group}]\n";
+ foreach ($settings as $key => $value) {
+ if (is_array($value)) {
+ foreach ($value as $_key => $_value) {
+ $new_config .= sprintf('%s="%s"', "{$key}[{$_key}]", addslashes($_value)). "\n";
+ }
+ } else {
+ $new_config .= sprintf('%s="%s"', $key, addslashes($value)). "\n";
+ }
+ }
+ $new_config .= "\n";
+ }
+
+ $fp = fopen($location, 'wb');
+ fwrite($fp, $new_config);
+ fclose($fp);
+ }
+}
+
+function postgresql_adodb() {
+ if (class_exists('ReflectionClass')) {
+ require_once dirname(__DIR__) . '/vendor/adodb/adodb-php/adodb-datadict.inc.php';
+ require_once dirname(__DIR__) . '/vendor/adodb/adodb-php/datadict/datadict-postgres.inc.php';
+ $refclass = new ReflectionClass('ADODB2_postgres');
+ $refmethod = $refclass->getMethod('ChangeTableSQL');
+ $implclass = $refmethod->getDeclaringClass();
+ if ($implclass->name === 'ADODB2_postgres') {
+ return true;
+ }
+ return false;
+ } else {
+ // Can't even do the test, hope the user is able to handle the situation him/serself.
+ return true;
+ }
+}
+
+$checks = $todo = array();
+$checks['version_compare'] = version_compare($installed_version, UPGRADE_VERSION) === -1;
+$checks['config_writable'] = is_writable(CONFIG_PATH);
+$checks['db_connect'] = (bool) $db->dblink;
+$checks['installed_version'] = version_compare($installed_version, '0.9.6') === 1;
+$todo['config_writable'] = 'Please make sure that the file at ' . CONFIG_PATH . ' is writable.';
+$todo['db_connect'] = 'Connection to the database could not be established. Check your config.';
+$todo['version_compare'] = 'No newer version than yours can be installed with this upgrader.';
+$todo['installed_version'] = 'An upgrade from Flyspray versions lower than 0.9.6 is not possible.
+ You will have to upgrade manually to at least 0.9.6, the scripts which do that are included in all Flyspray releases <= 0.9.8.';
+
+if ($conf['database']['dbtype'] == 'pgsql') {
+ $checks['postgresql_adodb'] = (bool) postgresql_adodb();
+ $todo['postgresql_adodb'] = 'You have a version of ADOdb that does not contain overridden version of method ChangeTableSQL for PostgreSQL. '
+ . 'Please copy setup/upgrade/1.0/datadict-postgres.inc.php to '
+ . 'vendor/adodb/adodb-php/datadict/ before proceeding with the upgrade process.';
+}
+
+$upgrade_possible = true;
+foreach ($checks as $check => $result) {
+ if ($result !== true) {
+ $upgrade_possible = false;
+ $page->assign('todo', $todo[$check]);
+ break;
+ }
+}
+
+if (isset($upgrade_info['options'])) {
+ // piece of HTML which adds user input, quick and dirty*/
+ $page->assign('upgrade_options', implode('', $upgrade_info['options']));
+}
+
+$page->assign('index', APPLICATION_SETUP_INDEX);
+$page->uses('checks', 'fs', 'upgrade_possible');
+$page->assign('installed_version', $installed_version);
+
+$page->display('upgrade.tpl');
+
+// Functions for checking and fixing possible duplicate entries
+// in database for those tables that now have a unique index.
+
+function fix_duplicate_list_entries($doit=true) {
+ global $db,$uplog;
+
+ // Categories need a bit more thinking. A real life example from
+ // my own database: A big project originally written (horrible!)
+ // in VB6, that I ported to .NET -environment. Categories:
+ // BackOfficer (main category)
+ // -> Reports (subcategory - should be allowed)
+ // BackOfficer.NET (main category)
+ // -> Reports (subcategory - should be allowed)
+ // -> Reports (I added a fake duplicate - should not be allowed)
+
+ $sql = $db->query('SELECT MIN(os_id) id, project_id, os_name
+ FROM {list_os}
+ GROUP BY project_id, os_name
+ HAVING COUNT(*) > 1');
+ $dups = $db->fetchAllArray($sql);
+ if (count($dups) > 0) {
+ if($doit){
+ fix_os_table($dups);
+ } else{
+ $uplog[]='<span class="warning">'.count($dups).' duplicate entries in {list_os}</span>';
+ }
+ }
+
+ $sql = $db->query('SELECT MIN(resolution_id) id, project_id, resolution_name
+ FROM {list_resolution}
+ GROUP BY project_id, resolution_name
+ HAVING COUNT(*) > 1');
+ $dups = $db->fetchAllArray($sql);
+ if (count($dups) > 0) {
+ if($doit){
+ fix_resolution_table($dups);
+ }else{
+ $uplog[]='<span class="warning">'.count($dups).' duplicate entries in {list_resolution}</span>';
+ }
+ }
+
+ $sql = $db->query('SELECT MIN(status_id) id, project_id, status_name
+ FROM {list_status}
+ GROUP BY project_id, status_name
+ HAVING COUNT(*) > 1');
+ $dups = $db->fetchAllArray($sql);
+ if (count($dups) > 0) {
+ if($doit){
+ fix_status_table($dups);
+ }else{
+ $uplog[]='<span class="warning">'.count($dups).' duplicate entries in {list_status}</span>';
+ }
+ }
+ $sql = $db->query('SELECT MIN(tasktype_id) id, project_id, tasktype_name
+ FROM {list_tasktype}
+ GROUP BY project_id, tasktype_name
+ HAVING COUNT(*) > 1');
+ $dups = $db->fetchAllArray($sql);
+ if (count($dups) > 0) {
+ if($doit){
+ fix_tasktype_table($dups);
+ }else{
+ $uplog[]='<span class="warning">'.count($dups).' duplicate entries in {list_tasktype}</span>';
+ }
+ }
+
+ $sql = $db->query('SELECT MIN(version_id) id, project_id, version_name
+ FROM {list_version}
+ GROUP BY project_id, version_name
+ HAVING COUNT(*) > 1');
+ $dups = $db->fetchAllArray($sql);
+ if (count($dups) > 0) {
+ if($doit){
+ fix_version_table($dups);
+ }else{
+ $uplog[]='<span class="warning">'.count($dups).' duplicate entries in {list_version}</span>';
+ }
+ }
+}
+
+function fix_os_table($dups) {
+ global $db;
+
+ foreach ($dups as $dup) {
+ $update_id = $dup['id'];
+
+ $sql = $db->query('SELECT os_id id
+ FROM {list_os}
+ WHERE project_id = ? AND os_name = ?',
+ array($dup['project_id'], $dup['os_name']));
+ $entries = $db->fetchAllArray($sql);
+ foreach ($entries as $entry) {
+ if ($entry['id'] == $update_id) {
+ continue;
+ }
+
+ $db->query('UPDATE {tasks}
+ SET operating_system = ?
+ WHERE operating_system = ?',
+ array($update_id, $entry['id']));
+ $db->query('DELETE FROM {list_os} WHERE os_id = ?', array($entry['id']));
+ }
+ }
+}
+
+function fix_resolution_table($dups) {
+ global $db;
+
+ foreach ($dups as $dup) {
+ $update_id = $dup['id'];
+
+ $sql = $db->query('SELECT resolution_id id
+ FROM {list_resolution}
+ WHERE project_id = ? AND resolution_name = ?',
+ array($dup['project_id'], $dup['resolution_name']));
+ $entries = $db->fetchAllArray($sql);
+ foreach ($entries as $entry) {
+ if ($entry['id'] == $update_id) {
+ continue;
+ }
+
+ $db->query('UPDATE {tasks}
+ SET resolution_reason = ?
+ WHERE resolution_reason = ?',
+ array($update_id, $entry['id']));
+ $db->query('DELETE FROM {list_resolution} WHERE resolution_id = ?', array($entry['id']));
+ }
+ }
+}
+
+function fix_status_table($dups) {
+ global $db;
+
+ foreach ($dups as $dup) {
+ $update_id = $dup['id'];
+
+ $sql = $db->query('SELECT status_id id
+ FROM {list_status}
+ WHERE project_id = ? AND status_name = ?',
+ array($dup['project_id'], $dup['status_name']));
+ $entries = $db->fetchAllArray($sql);
+ foreach ($entries as $entry) {
+ if ($entry['id'] == $update_id) {
+ continue;
+ }
+
+ $db->query('UPDATE {tasks}
+ SET item_status = ?
+ WHERE item_status = ?',
+ array($update_id, $entry['id']));
+ $db->query('DELETE FROM {list_status} WHERE status_id = ?', array($entry['id']));
+ }
+ }
+}
+
+function fix_tasktype_table($dups) {
+ global $db;
+
+ foreach ($dups as $dup) {
+ $update_id = $dup['id'];
+
+ $sql = $db->query('SELECT tasktype_id id
+ FROM {list_tasktype}
+ WHERE project_id = ? AND tasktype_name = ?',
+ array($dup['project_id'], $dup['tasktype_name']));
+ $entries = $db->fetchAllArray($sql);
+ foreach ($entries as $entry) {
+ if ($entry['id'] == $update_id) {
+ continue;
+ }
+
+ $db->query('UPDATE {tasks}
+ SET task_type = ?
+ WHERE task_type = ?',
+ array($update_id, $entry['id']));
+ $db->query('DELETE FROM {list_tasktype} WHERE tasktype_id = ?', array($entry['id']));
+ }
+ }
+}
+
+function fix_version_table($dups) {
+ global $db;
+
+ foreach ($dups as $dup) {
+ $update_id = $dup['id'];
+
+ $sql = $db->query('SELECT version_id id
+ FROM {list_version}
+ WHERE project_id = ? AND version_name = ?',
+ array($dup['project_id'], $dup['version_name']));
+ $entries = $db->fetchAllArray($sql);
+ foreach ($entries as $entry) {
+ if ($entry['id'] == $update_id) {
+ continue;
+ }
+
+ $db->query('UPDATE {tasks}
+ SET product_version = ?
+ WHERE product_version = ?',
+ array($update_id, $entry['id']));
+ $db->query('DELETE FROM {list_version} WHERE version_id = ?', array($entry['id']));
+ }
+ }
+}
+
+// Just a sketch on how database columns could be updated to the new format.
+// Not tested for errors or used anywhere yet.
+
+function convert_old_entries($table, $column, $key) {
+ global $db;
+
+ // Assuming that anything not beginning with < was made with older
+ // versions of flyspray. This will not catch neither those old entries
+ // where the user for some reason really added paragraph tags nor those
+ // made with development version before fixing ckeditors configuration
+ // settings. You can't have everything in a limited time frame, this
+ // should be just good enough.
+ $sql = $db->query("SELECT $key, $column "
+ . "FROM {". $table . "} "
+ . "WHERE $column NOT LIKE '<%'");
+ $entries = $db->fetchAllArray($sql);
+
+ # We should probably better use existing and proven filters for the conversions
+ # maybe this or existing dokuwiki functionality?
+ # $out=html2wiki($input, 'wikistyle'); and $out=wiki2html($input, 'wikistyle')
+
+ foreach ($entries as $entry) {
+ $id = $entry[$key];
+ $data = $entry[$column];
+
+ if (version_compare(PHP_VERSION, '5.4.0') >= 0) {
+ $data = htmlspecialchars($data, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');
+ } else{
+ $data = htmlspecialchars($data, ENT_QUOTES , 'UTF-8');
+ }
+ // Convert two or more line breaks to paragrahs, Windows/Unix/Linux formats
+ $data = preg_replace('/(\h*\r?\n)+\h*\r?\n/', "</p><p>", $data);
+ // Data coming from Macs has only carriage returns, and couldn't say
+ // \r?\n? in the previous regex, it would also have matched nothing.
+ // Even a short word like "it" has three nothings in it, one before
+ // i, one between i and t and one after t...
+ $data = preg_replace('/(\h*\r)+\h*\r/', "</p><p>", $data);
+ // Remaining single line breaks
+ $data = preg_replace('/\h*\r?\n/', "<br/>", $data);
+ $data = preg_replace('/\h*\r/', "<br/>", $data);
+ // Remove final extra break, if the data to converted ended with a line break
+ $data = preg_replace('#<br/>$#', '', $data);
+ // Remove final extra paragraph tags, if the data to converted ended with
+ // more than one line breaks
+ $data = preg_replace('#</p><p>$#', '', $data);
+ // Enclose the whole in paragraph tags, so it looks
+ // the same as what ckeditor produces.
+ $data = '<p>' . $data . '</p>';
+
+ $db->query("UPDATE {". $table . "} "
+ . "SET $column = ?"
+ . "WHERE $key = ?",
+ array($data, $id));
+ }
+}
diff --git a/setup/upgrade/0.9.9.2/flyspray-install.xml b/setup/upgrade/0.9.9.2/flyspray-install.xml
new file mode 100644
index 0000000..eac0638
--- /dev/null
+++ b/setup/upgrade/0.9.9.2/flyspray-install.xml
@@ -0,0 +1,1049 @@
+<?xml version="1.0"?>
+<schema version="0.3">
+ <table name="admin_requests">
+ <field name="request_id" type="I" size="5">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="project_id" type="I" size="5">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="task_id" type="I" size="5">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="submitted_by" type="I" size="5">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="request_type" type="I" size="2">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="reason_given" type="X">
+ <NOTNULL/>
+ </field>
+ <field name="time_submitted" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="resolved_by" type="I" size="5">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="time_resolved" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="deny_reason" type="C" size="255">
+ <NOTNULL/>
+ </field>
+ </table>
+ <table name="assigned">
+ <field name="assigned_id" type="I" size="10">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="task_id" type="I" size="10">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="user_id" type="I" size="5">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="task_user">
+ <UNIQUE/>
+ <col>task_id</col>
+ <col>user_id</col>
+ </index>
+ <index name="task_id_assigned">
+ <col>task_id</col>
+ <col>user_id</col>
+ </index>
+ </table>
+ <table name="attachments">
+ <field name="attachment_id" type="I" size="5">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="task_id" type="I" size="10">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="comment_id" type="I" size="10">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="orig_name" type="C" size="255">
+ <NOTNULL/>
+ </field>
+ <field name="file_name" type="C" size="30">
+ <NOTNULL/>
+ </field>
+ <field name="file_type" type="C" size="50">
+ <NOTNULL/>
+ </field>
+ <field name="file_size" type="I" size="20">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="added_by" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="date_added" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="task_id_attachments">
+ <col>task_id</col>
+ <col>comment_id</col>
+ </index>
+ </table>
+ <table name="cache">
+ <field name="id" type="I" size="6">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="type" type="C" size="4">
+ <NOTNULL/>
+ </field>
+ <field name="content" type="X">
+ <NOTNULL/>
+ </field>
+ <field name="topic" type="C" size="30">
+ <NOTNULL/>
+ </field>
+ <field name="last_updated" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="project_id" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="max_items" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="cache_type">
+ <UNIQUE/>
+ <col>type</col>
+ <col>topic</col>
+ <col>project_id</col>
+ <col>max_items</col>
+ </index>
+ </table>
+ <table name="comments">
+ <field name="comment_id" type="I" size="10">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="task_id" type="I" size="10">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="date_added" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="user_id" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="comment_text" type="X">
+ <NOTNULL/>
+ </field>
+ <field name="last_edited_time" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="task_id_comments">
+ <col>task_id</col>
+ </index>
+ </table>
+ <table name="dependencies">
+ <field name="depend_id" type="I" size="10">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="task_id" type="I" size="10">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="dep_task_id" type="I" size="10">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="task_id_deps">
+ <UNIQUE/>
+ <col>task_id</col>
+ <col>dep_task_id</col>
+ </index>
+ </table>
+ <table name="groups">
+ <field name="group_id" type="I" size="3">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="group_name" type="C" size="20">
+ <NOTNULL/>
+ </field>
+ <field name="group_desc" type="C" size="150">
+ <NOTNULL/>
+ </field>
+ <field name="project_id" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="is_admin" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="manage_project" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="view_tasks" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="open_new_tasks" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="modify_own_tasks" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="modify_all_tasks" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="view_comments" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="add_comments" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="edit_comments" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="edit_own_comments" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="delete_comments" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="create_attachments" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="delete_attachments" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="view_history" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="close_own_tasks" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="close_other_tasks" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="assign_to_self" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="assign_others_to_self" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="add_to_assignees" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="view_reports" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="add_votes" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="edit_assignments" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="group_open" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="group_name">
+ <UNIQUE/>
+ <col>group_name</col>
+ <col>project_id</col>
+ </index>
+ <index name="belongs_to_project">
+ <col>project_id</col>
+ </index>
+ </table>
+ <table name="history">
+ <field name="history_id" type="I" size="10">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="task_id" type="I" size="10">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="user_id" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="event_date" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="event_type" type="I" size="2">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="field_changed" type="C" size="50">
+ <NOTNULL/>
+ </field>
+ <field name="old_value" type="X" />
+ <field name="new_value" type="X" />
+ <index name="idx_task_id">
+ <col>task_id</col>
+ </index>
+ </table>
+ <table name="list_category">
+ <field name="category_id" type="I" size="3">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="project_id" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="category_name" type="C" size="30">
+ <NOTNULL/>
+ </field>
+ <field name="show_in_list" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="category_owner" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="lft" type="I" size="10">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ <UNSIGNED/>
+ </field>
+ <field name="rgt" type="I" size="10">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ <UNSIGNED/>
+ </field>
+ <index name="project_id_cat">
+ <col>project_id</col>
+ </index>
+ </table>
+ <table name="list_os">
+ <field name="os_id" type="I" size="3">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="project_id" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="os_name" type="C" size="20">
+ <NOTNULL/>
+ </field>
+ <field name="list_position" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="show_in_list" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="project_id_os">
+ <col>project_id</col>
+ </index>
+ </table>
+ <table name="list_resolution">
+ <field name="resolution_id" type="I" size="3">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="resolution_name" type="C" size="30">
+ <NOTNULL/>
+ </field>
+ <field name="list_position" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="show_in_list" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="project_id" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="project_id_res">
+ <col>project_id</col>
+ </index>
+ </table>
+ <table name="list_status">
+ <field name="status_id" type="I" size="3">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="status_name" type="C" size="20">
+ <NOTNULL/>
+ </field>
+ <field name="list_position" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="show_in_list" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="project_id" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="project_id_status">
+ <col>project_id</col>
+ </index>
+ </table>
+ <table name="list_tasktype">
+ <field name="tasktype_id" type="I" size="3">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="tasktype_name" type="C" size="20">
+ <NOTNULL/>
+ </field>
+ <field name="list_position" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="show_in_list" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="project_id" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="project_id_tt">
+ <col>project_id</col>
+ </index>
+ </table>
+ <table name="list_version">
+ <field name="version_id" type="I" size="3">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="project_id" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="version_name" type="C" size="20">
+ <NOTNULL/>
+ </field>
+ <field name="list_position" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="show_in_list" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="version_tense" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="project_id_version">
+ <col>project_id</col>
+ <col>version_tense</col>
+ </index>
+ </table>
+ <table name="notification_messages">
+ <field name="message_id" type="I" size="10">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="message_subject" type="X">
+ <NOTNULL/>
+ </field>
+ <field name="message_body" type="X">
+ <NOTNULL/>
+ </field>
+ <field name="time_created" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ </table>
+ <table name="notification_recipients">
+ <field name="recipient_id" type="I" size="10">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="message_id" type="I" size="10">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="notify_method" type="C" size="1">
+ <NOTNULL/>
+ </field>
+ <field name="notify_address" type="C" size="100">
+ <NOTNULL/>
+ </field>
+ </table>
+ <table name="notifications">
+ <field name="notify_id" type="I" size="10">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="task_id" type="I" size="10">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="user_id" type="I" size="5">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="task_id_notifs">
+ <UNIQUE/>
+ <col>task_id</col>
+ <col>user_id</col>
+ </index>
+ </table>
+ <table name="prefs">
+ <field name="pref_id" type="I" size="1">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="pref_name" type="C" size="20">
+ <NOTNULL/>
+ </field>
+ <field name="pref_value" type="C" size="250">
+ <DEFAULT value="0"/>
+ <NOTNULL/>
+ </field>
+ </table>
+ <table name="projects">
+ <field name="project_id" type="I" size="3">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="project_title" type="C" size="100">
+ <NOTNULL/>
+ </field>
+ <field name="theme_style" type="C" size="20">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="default_cat_owner" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="intro_message" type="X">
+ <NOTNULL/>
+ <DEFAULT value=""/>
+ </field>
+ <field name="project_is_active" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="visible_columns" type="C" size="255">
+ <NOTNULL/>
+ </field>
+ <field name="others_view" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="anon_open" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="notify_email" type="X">
+ <NOTNULL/>
+ <DEFAULT value=""/>
+ </field>
+ <field name="notify_jabber" type="X">
+ <NOTNULL/>
+ <DEFAULT value=""/>
+ </field>
+ <field name="notify_reply" type="X">
+ <NOTNULL/>
+ <DEFAULT value=""/>
+ </field>
+ <field name="notify_types" type="C" size="100">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="feed_img_url" type="X">
+ <NOTNULL/>
+ <DEFAULT value=""/>
+ </field>
+ <field name="feed_description" type="X">
+ <NOTNULL/>
+ <DEFAULT value=""/>
+ </field>
+ <field name="notify_subject" type="C" size="100">
+ <NOTNULL/>
+ <DEFAULT value=""/>
+ </field>
+ <field name="lang_code" type="C" size="10">
+ <NOTNULL/>
+ </field>
+ <field name="comment_closed" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="auto_assign" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="last_updated" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="default_task" type="X">
+ <NOTNULL/>
+ </field>
+ <field name="default_entry" type="C" size="8">
+ <NOTNULL/>
+ <DEFAULT value="index"/>
+ </field>
+ </table>
+ <table name="registrations">
+ <field name="reg_id" type="I" size="10">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="reg_time" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="confirm_code" type="C" size="20">
+ <NOTNULL/>
+ </field>
+ <field name="user_name" type="C" size="32">
+ <NOTNULL/>
+ </field>
+ <field name="real_name" type="C" size="100">
+ <NOTNULL/>
+ </field>
+ <field name="email_address" type="C" size="100">
+ <NOTNULL/>
+ </field>
+ <field name="jabber_id" type="C" size="100">
+ <NOTNULL/>
+ </field>
+ <field name="notify_type" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="magic_url" type="C" size="40">
+ <NOTNULL/>
+ </field>
+ <field name="time_zone" type="I" size="6">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ </table>
+ <table name="related">
+ <field name="related_id" type="I" size="10">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="this_task" type="I" size="10">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="related_task" type="I" size="10">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="is_duplicate" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="this_task">
+ <UNIQUE/>
+ <col>this_task</col>
+ <col>related_task</col>
+ <col>is_duplicate</col>
+ </index>
+ </table>
+ <table name="reminders">
+ <field name="reminder_id" type="I" size="10">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="task_id" type="I" size="10">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="to_user_id" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="from_user_id" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="start_time" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="how_often" type="I" size="12">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="last_sent" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="reminder_message" type="X">
+ <NOTNULL/>
+ </field>
+ </table>
+ <table name="searches">
+ <field name="id" type="I" size="11">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="user_id" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="name" type="C" size="50">
+ <NOTNULL/>
+ </field>
+ <field name="search_string" type="X">
+ <NOTNULL/>
+ </field>
+ <field name="time" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ </table>
+ <table name="tasks">
+ <field name="task_id" type="I" size="10">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="project_id" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="task_type" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="date_opened" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="opened_by" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="is_closed" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="date_closed" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="closed_by" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="closure_comment" type="X">
+ <NOTNULL/>
+ </field>
+ <field name="item_summary" type="C" size="100">
+ <NOTNULL/>
+ </field>
+ <field name="detailed_desc" type="X">
+ <NOTNULL/>
+ </field>
+ <field name="item_status" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="resolution_reason" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="1"/>
+ </field>
+ <field name="product_category" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="product_version" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="closedby_version" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="operating_system" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="task_severity" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="task_priority" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="last_edited_by" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="last_edited_time" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="percent_complete" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="mark_private" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="due_date" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="anon_email" type="C" size="100">
+ <NOTNULL/>
+ <DEFAULT value=""/>
+ </field>
+ <field name="task_token" type="C" size="32">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="attached_to_project">
+ <col>project_id</col>
+ </index>
+ <index name="task_severity">
+ <col>task_severity</col>
+ </index>
+ <index name="task_type">
+ <col>task_type</col>
+ </index>
+ <index name="product_category">
+ <col>product_category</col>
+ </index>
+ <index name="item_status">
+ <col>item_status</col>
+ </index>
+ <index name="is_closed">
+ <col>is_closed</col>
+ </index>
+ <index name="closedby_version">
+ <col>closedby_version</col>
+ </index>
+ <index name="due_date">
+ <col>due_date</col>
+ </index>
+ </table>
+ <table name="users">
+ <field name="user_id" type="I" size="3">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="user_name" type="C" size="32">
+ <NOTNULL/>
+ </field>
+ <field name="user_pass" type="C" size="40"/>
+ <field name="real_name" type="C" size="100">
+ <NOTNULL/>
+ </field>
+ <field name="jabber_id" type="C" size="100">
+ <NOTNULL/>
+ </field>
+ <field name="email_address" type="C" size="100">
+ <NOTNULL/>
+ </field>
+ <field name="notify_type" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="notify_own" type="I" size="6">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="account_enabled" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="dateformat" type="C" size="30">
+ <NOTNULL/>
+ <DEFAULT value=""/>
+ </field>
+ <field name="dateformat_extended" type="C" size="30">
+ <NOTNULL/>
+ <DEFAULT value=""/>
+ </field>
+ <field name="magic_url" type="C" size="40">
+ <NOTNULL/>
+ <DEFAULT value=""/>
+ </field>
+ <field name="tasks_perpage" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="register_date" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="time_zone" type="I" size="6">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="login_attempts" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="lock_until" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="user_name">
+ <UNIQUE/>
+ <col>user_name</col>
+ </index>
+ </table>
+ <table name="users_in_groups">
+ <field name="record_id" type="I" size="5">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="user_id" type="I" size="5">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="group_id" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="group_id_uig">
+ <UNIQUE/>
+ <col>group_id</col>
+ <col>user_id</col>
+ </index>
+ <index name="user_id_uig">
+ <col>user_id</col>
+ </index>
+ </table>
+ <table name="votes">
+ <field name="vote_id" type="I" size="11">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="user_id" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="task_id" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="date_time" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ </table>
+ <sql>
+ <query>INSERT INTO groups VALUES (DEFAULT, 'Admin', 'Members have unlimited access to all functionality.', 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1);</query>
+ <query>INSERT INTO groups VALUES (DEFAULT, 'Developers', 'Global Developers for all projects', 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1);</query>
+ <query>INSERT INTO groups VALUES (DEFAULT, 'Reporters', 'Open new tasks / add comments in all projects', 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1);</query>
+ <query>INSERT INTO groups VALUES (DEFAULT, 'Basic', 'Members can login, relying upon Project permissions only', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1);</query>
+ <query>INSERT INTO groups VALUES (DEFAULT, 'Pending', 'Users who are awaiting approval of their accounts.', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);</query>
+ <query>INSERT INTO groups VALUES (DEFAULT, 'Project Managers', 'Permission to do anything related to the Default Project.', 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1);</query>
+ <query>INSERT INTO history VALUES (DEFAULT, 1, 1, 1130024797, 1, '', '', '');</query>
+ <query>INSERT INTO list_category VALUES (DEFAULT, 1, 'Backend / Core', 1, 0, 2, 3);</query>
+ <query>INSERT INTO list_category VALUES (DEFAULT, 0, 'root', 0, 0, 1, 2);</query>
+ <query>INSERT INTO list_category VALUES (DEFAULT, 1, 'root', 0, 0, 1, 4);</query>
+ <query>INSERT INTO list_os VALUES (DEFAULT, 1, 'All', 1, 1);</query>
+ <query>INSERT INTO list_os VALUES (DEFAULT, 1, 'Windows', 2, 1);</query>
+ <query>INSERT INTO list_os VALUES (DEFAULT, 1, 'Linux', 3, 1);</query>
+ <query>INSERT INTO list_os VALUES (DEFAULT, 1, 'Mac OS', 4, 1);</query>
+ <query>INSERT INTO list_resolution VALUES (DEFAULT, 'Not a bug', 1, 1, 0);</query>
+ <query>INSERT INTO list_resolution VALUES (DEFAULT, 'Won''t fix', 2, 1, 0);</query>
+ <query>INSERT INTO list_resolution VALUES (DEFAULT, 'Won''t implement', 3, 1, 0);</query>
+ <query>INSERT INTO list_resolution VALUES (DEFAULT, 'Works for me', 4, 1, 0);</query>
+ <query>INSERT INTO list_resolution VALUES (DEFAULT, 'Deferred', 5, 1, 0);</query>
+ <query>INSERT INTO list_resolution VALUES (DEFAULT, 'Duplicate', 6, 1, 0);</query>
+ <query>INSERT INTO list_resolution VALUES (DEFAULT, 'Fixed', 7, 1, 0);</query>
+ <query>INSERT INTO list_resolution VALUES (DEFAULT, 'Implemented', 8, 1, 0);</query>
+ <query>INSERT INTO list_tasktype VALUES (DEFAULT, 'Bug Report', 1, 1, 0);</query>
+ <query>INSERT INTO list_tasktype VALUES (DEFAULT, 'Feature Request', 2, 1, 0);</query>
+ <query>INSERT INTO list_version VALUES (DEFAULT, 1, 'Development', 1, 1, 2);</query>
+ <query>INSERT INTO list_status (status_name, list_position, show_in_list, project_id) VALUES ('Unconfirmed', 1, 1, 0)</query>
+ <query>INSERT INTO list_status (status_name, list_position, show_in_list, project_id) VALUES ('New', 2, 1, 0)</query>
+ <query>INSERT INTO list_status (status_name, list_position, show_in_list, project_id) VALUES ('Assigned', 3, 1, 0)</query>
+ <query>INSERT INTO list_status (status_name, list_position, show_in_list, project_id) VALUES ('Researching', 4, 1, 0)</query>
+ <query>INSERT INTO list_status (status_name, list_position, show_in_list, project_id) VALUES ('Waiting on Customer', 5, 1, 0)</query>
+ <query>INSERT INTO list_status (status_name, list_position, show_in_list, project_id) VALUES ('Requires testing', 6, 1, 0)</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'fs_ver', '0.9.9');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'jabber_server', '');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'jabber_port', '5222');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'jabber_username', '');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'jabber_password', '');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'anon_group', '4');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'user_notify', '1');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'admin_email', 'flyspray@example.com');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'lang_code', 'en');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'spam_proof', '1');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'default_project', '1');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'dateformat', '');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'dateformat_extended', '');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'anon_reg', '1');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'global_theme', 'CleanFS');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'visible_columns', 'id project category tasktype severity summary status progress');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'smtp_server', '');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'smtp_user', '');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'smtp_pass', '');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'page_title', 'Flyspray::');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'notify_registration', '0');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'jabber_ssl', '0');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'last_update_check', '0');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'cache_feeds', '1');</query>
+ <query>INSERT INTO projects VALUES (DEFAULT, 'Default Project', 'CleanFS', 0, 'Welcome to your first Flyspray project! We hope that Flyspray provides you with many hours of increased productivity. If you have any issues, go to http://flyspray.org/support. You can customise this message by clicking the **Manage Project** link in the menu above...', 1, 'id category tasktype severity summary status progress', 1, 0, '', '', NULL, '0', NULL, NULL, '', 'en', 0, 0, 0, NULL, 'index');</query>
+ <query>INSERT INTO tasks VALUES (1, 1, 1, 1130024797, 1, 0, 0, 0, ' ', 'Sample Task', 'This isn''t a real task. You should close it and start opening some real tasks.', 2, 1, 1, 1, 0, 1, 1, 2, 0, 0, 0, 0, 0, '', '0');</query>
+ <query>INSERT INTO users VALUES (DEFAULT, 'super', '1b3231655cebb7a1f783eddf27d254ca', 'Mr Super User', 'super@example.com', 'super@example.com', 0, 1, 1, '', '', 25, 0, 0, 0, 0, 0);</query>
+ <query>INSERT INTO users_in_groups VALUES (DEFAULT, 1, 1);</query>
+ </sql>
+</schema>
diff --git a/setup/upgrade/0.9.9.2/lowercase_emails.php b/setup/upgrade/0.9.9.2/lowercase_emails.php
new file mode 100644
index 0000000..24fd28e
--- /dev/null
+++ b/setup/upgrade/0.9.9.2/lowercase_emails.php
@@ -0,0 +1,6 @@
+<?php
+
+$db->query('UPDATE {users} SET email_address = LOWER(email_address), jabber_id = LOWER(jabber_id)');
+
+?>
+
diff --git a/setup/upgrade/0.9.9.2/update_users.xml b/setup/upgrade/0.9.9.2/update_users.xml
new file mode 100644
index 0000000..591a1bb
--- /dev/null
+++ b/setup/upgrade/0.9.9.2/update_users.xml
@@ -0,0 +1,70 @@
+<?xml version="1.0"?>
+<schema version="0.3">
+ <table name="users">
+ <field name="user_id" type="I" size="3">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="user_name" type="C" size="32">
+ <NOTNULL/>
+ </field>
+ <field name="user_pass" type="C" size="40"/>
+ <field name="real_name" type="C" size="100">
+ <NOTNULL/>
+ </field>
+ <field name="jabber_id" type="C" size="100">
+ <NOTNULL/>
+ </field>
+ <field name="email_address" type="C" size="100">
+ <NOTNULL/>
+ </field>
+ <field name="notify_type" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="notify_own" type="I" size="6">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="account_enabled" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="dateformat" type="C" size="30">
+ <NOTNULL/>
+ <DEFAULT value=""/>
+ </field>
+ <field name="dateformat_extended" type="C" size="30">
+ <NOTNULL/>
+ <DEFAULT value=""/>
+ </field>
+ <field name="magic_url" type="C" size="40">
+ <NOTNULL/>
+ <DEFAULT value=""/>
+ </field>
+ <field name="tasks_perpage" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="register_date" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="time_zone" type="I" size="6">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="login_attempts" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="lock_until" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="user_name">
+ <UNIQUE/>
+ <col>user_name</col>
+ </index>
+ </table>
+</schema> \ No newline at end of file
diff --git a/setup/upgrade/0.9.9.2/upgrade.info b/setup/upgrade/0.9.9.2/upgrade.info
new file mode 100644
index 0000000..4ea91dd
--- /dev/null
+++ b/setup/upgrade/0.9.9.2/upgrade.info
@@ -0,0 +1,34 @@
+[defaultupgrade]
+1="update_users.xml"
+2="lowercase_emails.php"
+
+
+[develupgrade]
+1="update_users.xml"
+
+[fsprefs]
+fs_ver="0.9.7" ; doesn't matter which version
+jabber_server=""
+jabber_port="5222"
+jabber_username=""
+jabber_password=""
+anon_group="0"
+user_notify="1"
+admin_email="flyspray@example.com"
+lang_code="en"
+spam_proof="1"
+default_project="1"
+dateformat=""
+dateformat_extended=""
+anon_reg="1"
+page_title="Flyspray:: "
+notify_registration="0"
+jabber_ssl="0"
+last_update_check="0"
+cache_feeds="1"
+global_theme="CleanFS"
+visible_columns="id project tasktype severity summary status progress"
+smtp_server=""
+smtp_user=""
+smtp_pass=""
+lock_for="5" \ No newline at end of file
diff --git a/setup/upgrade/0.9.9.4/flyspray-install.xml b/setup/upgrade/0.9.9.4/flyspray-install.xml
new file mode 100644
index 0000000..ae2de1d
--- /dev/null
+++ b/setup/upgrade/0.9.9.4/flyspray-install.xml
@@ -0,0 +1,1055 @@
+<?xml version="1.0"?>
+<schema version="0.3">
+ <table name="admin_requests">
+ <field name="request_id" type="I" size="5">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="project_id" type="I" size="5">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="task_id" type="I" size="5">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="submitted_by" type="I" size="5">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="request_type" type="I" size="2">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="reason_given" type="X">
+ <NOTNULL/>
+ </field>
+ <field name="time_submitted" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="resolved_by" type="I" size="5">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="time_resolved" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="deny_reason" type="C" size="255" />
+ </table>
+ <table name="assigned">
+ <field name="assigned_id" type="I" size="10">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="task_id" type="I" size="10">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="user_id" type="I" size="5">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="task_user">
+ <UNIQUE/>
+ <col>task_id</col>
+ <col>user_id</col>
+ </index>
+ <index name="task_id_assigned">
+ <col>task_id</col>
+ <col>user_id</col>
+ </index>
+ </table>
+ <table name="attachments">
+ <field name="attachment_id" type="I" size="5">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="task_id" type="I" size="10">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="comment_id" type="I" size="10">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="orig_name" type="C" size="255">
+ <NOTNULL/>
+ </field>
+ <field name="file_name" type="C" size="30">
+ <NOTNULL/>
+ </field>
+ <field name="file_type" type="C" size="50">
+ <NOTNULL/>
+ </field>
+ <field name="file_size" type="I" size="20">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="added_by" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="date_added" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="task_id_attachments">
+ <col>task_id</col>
+ <col>comment_id</col>
+ </index>
+ </table>
+ <table name="cache">
+ <field name="id" type="I" size="6">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="type" type="C" size="4">
+ <NOTNULL/>
+ </field>
+ <field name="content" type="XL">
+ <NOTNULL/>
+ </field>
+ <field name="topic" type="C" size="30">
+ <NOTNULL/>
+ </field>
+ <field name="last_updated" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="project_id" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="max_items" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="cache_type">
+ <UNIQUE/>
+ <col>type</col>
+ <col>topic</col>
+ <col>project_id</col>
+ <col>max_items</col>
+ </index>
+ <index name="cache_type_topic">
+ <col>type</col>
+ <col>topic</col>
+ </index>
+ </table>
+ <table name="comments">
+ <field name="comment_id" type="I" size="10">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="task_id" type="I" size="10">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="date_added" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="user_id" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="comment_text" type="X">
+ <NOTNULL/>
+ </field>
+ <field name="last_edited_time" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="task_id_comments">
+ <col>task_id</col>
+ </index>
+ </table>
+ <table name="dependencies">
+ <field name="depend_id" type="I" size="10">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="task_id" type="I" size="10">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="dep_task_id" type="I" size="10">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="task_id_deps">
+ <UNIQUE/>
+ <col>task_id</col>
+ <col>dep_task_id</col>
+ </index>
+ </table>
+ <table name="groups">
+ <field name="group_id" type="I" size="3">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="group_name" type="C" size="20">
+ <NOTNULL/>
+ </field>
+ <field name="group_desc" type="C" size="150">
+ <NOTNULL/>
+ </field>
+ <field name="project_id" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="is_admin" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="manage_project" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="view_tasks" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="open_new_tasks" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="modify_own_tasks" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="modify_all_tasks" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="view_comments" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="add_comments" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="edit_comments" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="edit_own_comments" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="delete_comments" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="create_attachments" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="delete_attachments" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="view_history" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="close_own_tasks" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="close_other_tasks" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="assign_to_self" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="assign_others_to_self" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="add_to_assignees" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="view_reports" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="add_votes" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="edit_assignments" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="show_as_assignees" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="group_open" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="group_name">
+ <UNIQUE/>
+ <col>group_name</col>
+ <col>project_id</col>
+ </index>
+ <index name="belongs_to_project">
+ <col>project_id</col>
+ </index>
+ </table>
+ <table name="history">
+ <field name="history_id" type="I" size="10">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="task_id" type="I" size="10">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="user_id" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="event_date" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="event_type" type="I" size="2">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="field_changed" type="C" size="50">
+ <NOTNULL/>
+ </field>
+ <field name="old_value" type="X" />
+ <field name="new_value" type="X" />
+ <index name="idx_task_id">
+ <col>task_id</col>
+ </index>
+ </table>
+ <table name="list_category">
+ <field name="category_id" type="I" size="3">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="project_id" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="category_name" type="C" size="30">
+ <NOTNULL/>
+ </field>
+ <field name="show_in_list" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="category_owner" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="lft" type="I" size="10">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ <UNSIGNED/>
+ </field>
+ <field name="rgt" type="I" size="10">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ <UNSIGNED/>
+ </field>
+ <index name="project_id_cat">
+ <col>project_id</col>
+ </index>
+ </table>
+ <table name="list_os">
+ <field name="os_id" type="I" size="3">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="project_id" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="os_name" type="C" size="20">
+ <NOTNULL/>
+ </field>
+ <field name="list_position" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="show_in_list" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="project_id_os">
+ <col>project_id</col>
+ </index>
+ </table>
+ <table name="list_resolution">
+ <field name="resolution_id" type="I" size="3">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="resolution_name" type="C" size="30">
+ <NOTNULL/>
+ </field>
+ <field name="list_position" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="show_in_list" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="project_id" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="project_id_res">
+ <col>project_id</col>
+ </index>
+ </table>
+ <table name="list_status">
+ <field name="status_id" type="I" size="3">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="status_name" type="C" size="20">
+ <NOTNULL/>
+ </field>
+ <field name="list_position" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="show_in_list" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="project_id" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="project_id_status">
+ <col>project_id</col>
+ </index>
+ </table>
+ <table name="list_tasktype">
+ <field name="tasktype_id" type="I" size="3">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="tasktype_name" type="C" size="20">
+ <NOTNULL/>
+ </field>
+ <field name="list_position" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="show_in_list" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="project_id" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="project_id_tt">
+ <col>project_id</col>
+ </index>
+ </table>
+ <table name="list_version">
+ <field name="version_id" type="I" size="3">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="project_id" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="version_name" type="C" size="20">
+ <NOTNULL/>
+ </field>
+ <field name="list_position" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="show_in_list" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="version_tense" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="project_id_version">
+ <col>project_id</col>
+ <col>version_tense</col>
+ </index>
+ </table>
+ <table name="notification_messages">
+ <field name="message_id" type="I" size="10">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="message_subject" type="X">
+ <NOTNULL/>
+ </field>
+ <field name="message_body" type="X">
+ <NOTNULL/>
+ </field>
+ <field name="time_created" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ </table>
+ <table name="notification_recipients">
+ <field name="recipient_id" type="I" size="10">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="message_id" type="I" size="10">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="notify_method" type="C" size="1">
+ <NOTNULL/>
+ </field>
+ <field name="notify_address" type="C" size="100">
+ <NOTNULL/>
+ </field>
+ </table>
+ <table name="notifications">
+ <field name="notify_id" type="I" size="10">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="task_id" type="I" size="10">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="user_id" type="I" size="5">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="task_id_notifs">
+ <UNIQUE/>
+ <col>task_id</col>
+ <col>user_id</col>
+ </index>
+ </table>
+ <table name="prefs">
+ <field name="pref_id" type="I" size="1">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="pref_name" type="C" size="20">
+ <NOTNULL/>
+ </field>
+ <field name="pref_value" type="C" size="250">
+ <DEFAULT value="0"/>
+ <NOTNULL/>
+ </field>
+ </table>
+ <table name="projects">
+ <field name="project_id" type="I" size="3">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="project_title" type="C" size="100">
+ <NOTNULL/>
+ </field>
+ <field name="theme_style" type="C" size="20">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="default_cat_owner" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="intro_message" type="X">
+ <NOTNULL/>
+ <DEFAULT value=""/>
+ </field>
+ <field name="project_is_active" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="visible_columns" type="C" size="255">
+ <NOTNULL/>
+ </field>
+ <field name="others_view" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="anon_open" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="notify_email" type="X">
+ <NOTNULL/>
+ <DEFAULT value=""/>
+ </field>
+ <field name="notify_jabber" type="X">
+ <NOTNULL/>
+ <DEFAULT value=""/>
+ </field>
+ <field name="notify_reply" type="X">
+ <NOTNULL/>
+ <DEFAULT value=""/>
+ </field>
+ <field name="notify_types" type="C" size="100">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="feed_img_url" type="X">
+ <NOTNULL/>
+ <DEFAULT value=""/>
+ </field>
+ <field name="feed_description" type="X">
+ <NOTNULL/>
+ <DEFAULT value=""/>
+ </field>
+ <field name="notify_subject" type="C" size="100">
+ <NOTNULL/>
+ <DEFAULT value=""/>
+ </field>
+ <field name="lang_code" type="C" size="10">
+ <NOTNULL/>
+ </field>
+ <field name="comment_closed" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="auto_assign" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="last_updated" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="default_task" type="X">
+ <NOTNULL/>
+ </field>
+ <field name="default_entry" type="C" size="8">
+ <NOTNULL/>
+ <DEFAULT value="index"/>
+ </field>
+ </table>
+ <table name="registrations">
+ <field name="reg_id" type="I" size="10">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="reg_time" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="confirm_code" type="C" size="20">
+ <NOTNULL/>
+ </field>
+ <field name="user_name" type="C" size="32">
+ <NOTNULL/>
+ </field>
+ <field name="real_name" type="C" size="100">
+ <NOTNULL/>
+ </field>
+ <field name="email_address" type="C" size="100">
+ <NOTNULL/>
+ </field>
+ <field name="jabber_id" type="C" size="100">
+ <NOTNULL/>
+ </field>
+ <field name="notify_type" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="magic_url" type="C" size="40">
+ <NOTNULL/>
+ </field>
+ <field name="time_zone" type="I" size="6">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ </table>
+ <table name="related">
+ <field name="related_id" type="I" size="10">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="this_task" type="I" size="10">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="related_task" type="I" size="10">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="is_duplicate" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="this_task">
+ <UNIQUE/>
+ <col>this_task</col>
+ <col>related_task</col>
+ <col>is_duplicate</col>
+ </index>
+ </table>
+ <table name="reminders">
+ <field name="reminder_id" type="I" size="10">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="task_id" type="I" size="10">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="to_user_id" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="from_user_id" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="start_time" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="how_often" type="I" size="12">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="last_sent" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="reminder_message" type="X">
+ <NOTNULL/>
+ </field>
+ </table>
+ <table name="searches">
+ <field name="id" type="I" size="11">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="user_id" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="name" type="C" size="50">
+ <NOTNULL/>
+ </field>
+ <field name="search_string" type="X">
+ <NOTNULL/>
+ </field>
+ <field name="time" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ </table>
+ <table name="tasks">
+ <field name="task_id" type="I" size="10">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="project_id" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="task_type" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="date_opened" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="opened_by" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="is_closed" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="date_closed" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="closed_by" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="closure_comment" type="X">
+ <NOTNULL/>
+ </field>
+ <field name="item_summary" type="C" size="100">
+ <NOTNULL/>
+ </field>
+ <field name="detailed_desc" type="X">
+ <NOTNULL/>
+ </field>
+ <field name="item_status" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="resolution_reason" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="1"/>
+ </field>
+ <field name="product_category" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="product_version" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="closedby_version" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="operating_system" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="task_severity" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="task_priority" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="last_edited_by" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="last_edited_time" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="percent_complete" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="mark_private" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="due_date" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="anon_email" type="C" size="100">
+ <NOTNULL/>
+ <DEFAULT value=""/>
+ </field>
+ <field name="task_token" type="C" size="32">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="attached_to_project">
+ <col>project_id</col>
+ </index>
+ <index name="task_severity">
+ <col>task_severity</col>
+ </index>
+ <index name="task_type">
+ <col>task_type</col>
+ </index>
+ <index name="product_category">
+ <col>product_category</col>
+ </index>
+ <index name="item_status">
+ <col>item_status</col>
+ </index>
+ <index name="is_closed">
+ <col>is_closed</col>
+ </index>
+ <index name="closedby_version">
+ <col>closedby_version</col>
+ </index>
+ <index name="due_date">
+ <col>due_date</col>
+ </index>
+ </table>
+ <table name="users">
+ <field name="user_id" type="I" size="3">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="user_name" type="C" size="32">
+ <NOTNULL/>
+ </field>
+ <field name="user_pass" type="C" size="40"/>
+ <field name="real_name" type="C" size="100">
+ <NOTNULL/>
+ </field>
+ <field name="jabber_id" type="C" size="100">
+ <NOTNULL/>
+ </field>
+ <field name="email_address" type="C" size="100">
+ <NOTNULL/>
+ </field>
+ <field name="notify_type" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="notify_own" type="I" size="6">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="account_enabled" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="dateformat" type="C" size="30">
+ <NOTNULL/>
+ <DEFAULT value=""/>
+ </field>
+ <field name="dateformat_extended" type="C" size="30">
+ <NOTNULL/>
+ <DEFAULT value=""/>
+ </field>
+ <field name="magic_url" type="C" size="40">
+ <NOTNULL/>
+ <DEFAULT value=""/>
+ </field>
+ <field name="tasks_perpage" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="register_date" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="time_zone" type="I" size="6">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="login_attempts" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="lock_until" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="user_name">
+ <UNIQUE/>
+ <col>user_name</col>
+ </index>
+ </table>
+ <table name="users_in_groups">
+ <field name="record_id" type="I" size="5">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="user_id" type="I" size="5">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="group_id" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="group_id_uig">
+ <UNIQUE/>
+ <col>group_id</col>
+ <col>user_id</col>
+ </index>
+ <index name="user_id_uig">
+ <col>user_id</col>
+ </index>
+ </table>
+ <table name="votes">
+ <field name="vote_id" type="I" size="11">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="user_id" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="task_id" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="date_time" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ </table>
+ <sql>
+ <query>INSERT INTO groups VALUES (DEFAULT, 'Admin', 'Members have unlimited access to all functionality.', 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0,1, 1);</query>
+ <query>INSERT INTO groups VALUES (DEFAULT, 'Developers', 'Global Developers for all projects', 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1,1, 1);</query>
+ <query>INSERT INTO groups VALUES (DEFAULT, 'Reporters', 'Open new tasks / add comments in all projects', 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1);</query>
+ <query>INSERT INTO groups VALUES (DEFAULT, 'Basic', 'Members can login, relying upon Project permissions only', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,0, 1);</query>
+ <query>INSERT INTO groups VALUES (DEFAULT, 'Pending', 'Users who are awaiting approval of their accounts.', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);</query>
+ <query>INSERT INTO groups VALUES (DEFAULT, 'Project Managers', 'Permission to do anything related to the Default Project.', 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1);</query>
+ <query>INSERT INTO history VALUES (DEFAULT, 1, 1, 1130024797, 1, '', '', '');</query>
+ <query>INSERT INTO list_category VALUES (DEFAULT, 1, 'Backend / Core', 1, 0, 2, 3);</query>
+ <query>INSERT INTO list_category VALUES (DEFAULT, 0, 'root', 0, 0, 1, 2);</query>
+ <query>INSERT INTO list_category VALUES (DEFAULT, 1, 'root', 0, 0, 1, 4);</query>
+ <query>INSERT INTO list_os VALUES (DEFAULT, 1, 'All', 1, 1);</query>
+ <query>INSERT INTO list_os VALUES (DEFAULT, 1, 'Windows', 2, 1);</query>
+ <query>INSERT INTO list_os VALUES (DEFAULT, 1, 'Linux', 3, 1);</query>
+ <query>INSERT INTO list_os VALUES (DEFAULT, 1, 'Mac OS', 4, 1);</query>
+ <query>INSERT INTO list_resolution VALUES (DEFAULT, 'Not a bug', 1, 1, 0);</query>
+ <query>INSERT INTO list_resolution VALUES (DEFAULT, 'Won''t fix', 2, 1, 0);</query>
+ <query>INSERT INTO list_resolution VALUES (DEFAULT, 'Won''t implement', 3, 1, 0);</query>
+ <query>INSERT INTO list_resolution VALUES (DEFAULT, 'Works for me', 4, 1, 0);</query>
+ <query>INSERT INTO list_resolution VALUES (DEFAULT, 'Deferred', 5, 1, 0);</query>
+ <query>INSERT INTO list_resolution VALUES (DEFAULT, 'Duplicate', 6, 1, 0);</query>
+ <query>INSERT INTO list_resolution VALUES (DEFAULT, 'Fixed', 7, 1, 0);</query>
+ <query>INSERT INTO list_resolution VALUES (DEFAULT, 'Implemented', 8, 1, 0);</query>
+ <query>INSERT INTO list_tasktype VALUES (DEFAULT, 'Bug Report', 1, 1, 0);</query>
+ <query>INSERT INTO list_tasktype VALUES (DEFAULT, 'Feature Request', 2, 1, 0);</query>
+ <query>INSERT INTO list_version VALUES (DEFAULT, 1, 'Development', 1, 1, 2);</query>
+ <query>INSERT INTO list_status (status_name, list_position, show_in_list, project_id) VALUES ('Unconfirmed', 1, 1, 0)</query>
+ <query>INSERT INTO list_status (status_name, list_position, show_in_list, project_id) VALUES ('New', 2, 1, 0)</query>
+ <query>INSERT INTO list_status (status_name, list_position, show_in_list, project_id) VALUES ('Assigned', 3, 1, 0)</query>
+ <query>INSERT INTO list_status (status_name, list_position, show_in_list, project_id) VALUES ('Researching', 4, 1, 0)</query>
+ <query>INSERT INTO list_status (status_name, list_position, show_in_list, project_id) VALUES ('Waiting on Customer', 5, 1, 0)</query>
+ <query>INSERT INTO list_status (status_name, list_position, show_in_list, project_id) VALUES ('Requires testing', 6, 1, 0)</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'fs_ver', '0.9.9');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'jabber_server', '');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'jabber_port', '5222');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'jabber_username', '');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'jabber_password', '');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'anon_group', '4');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'user_notify', '1');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'admin_email', 'flyspray@example.com');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'lang_code', 'en');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'spam_proof', '1');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'default_project', '1');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'dateformat', '');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'dateformat_extended', '');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'anon_reg', '1');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'global_theme', 'CleanFS');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'visible_columns', 'id project category tasktype severity summary status progress');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'smtp_server', '');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'smtp_user', '');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'smtp_pass', '');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'page_title', 'Flyspray::');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'notify_registration', '0');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'jabber_ssl', '0');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'last_update_check', '0');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'cache_feeds', '1');</query>
+ <query>INSERT INTO projects VALUES (DEFAULT, 'Default Project', 'CleanFS', 0, 'Welcome to your first Flyspray project! We hope that Flyspray provides you with many hours of increased productivity. If you have any issues, go to http://flyspray.org/support. You can customise this message by clicking the **Manage Project** link in the menu above...', 1, 'id category tasktype severity summary status progress', 1, 0, '', '', NULL, '0', NULL, NULL, '', 'en', 0, 0, 0, NULL, 'index');</query>
+ <query>INSERT INTO tasks VALUES (1, 1, 1, 1130024797, 1, 0, 0, 0, ' ', 'Sample Task', 'This isn''t a real task. You should close it and start opening some real tasks.', 2, 1, 1, 1, 0, 1, 1, 2, 0, 0, 0, 0, 0, '', '0');</query>
+ <query>INSERT INTO users VALUES (DEFAULT, 'super', '1b3231655cebb7a1f783eddf27d254ca', 'Mr Super User', 'super@example.com', 'super@example.com', 0, 1, 1, '', '', 25, 0, 0, 0, 0, 0);</query>
+ <query>INSERT INTO users_in_groups VALUES (DEFAULT, 1, 1);</query>
+ </sql>
+</schema>
diff --git a/setup/upgrade/0.9.9.4/upgrade.info b/setup/upgrade/0.9.9.4/upgrade.info
new file mode 100644
index 0000000..3acfddb
--- /dev/null
+++ b/setup/upgrade/0.9.9.4/upgrade.info
@@ -0,0 +1,32 @@
+[defaultupgrade]
+1="upgrade.xml"
+
+[develupgrade]
+1="upgrade.xml"
+
+[fsprefs]
+fs_ver="0.9.7" ; doesn't matter which version
+jabber_server=""
+jabber_port="5222"
+jabber_username=""
+jabber_password=""
+anon_group="0"
+user_notify="1"
+admin_email="flyspray@example.com"
+lang_code="en"
+spam_proof="1"
+default_project="1"
+dateformat=""
+dateformat_extended=""
+anon_reg="1"
+page_title="Flyspray:: "
+notify_registration="0"
+jabber_ssl="0"
+last_update_check="0"
+cache_feeds="1"
+global_theme="CleanFS"
+visible_columns="id project tasktype severity summary status progress"
+smtp_server=""
+smtp_user=""
+smtp_pass=""
+lock_for="5" \ No newline at end of file
diff --git a/setup/upgrade/0.9.9.4/upgrade.xml b/setup/upgrade/0.9.9.4/upgrade.xml
new file mode 100644
index 0000000..5953d91
--- /dev/null
+++ b/setup/upgrade/0.9.9.4/upgrade.xml
@@ -0,0 +1,199 @@
+<?xml version="1.0"?>
+<schema version="0.3">
+ <table name="groups">
+ <field name="group_id" type="I" size="3">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="group_name" type="C" size="20">
+ <NOTNULL/>
+ </field>
+ <field name="group_desc" type="C" size="150">
+ <NOTNULL/>
+ </field>
+ <field name="project_id" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="is_admin" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="manage_project" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="view_tasks" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="open_new_tasks" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="modify_own_tasks" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="modify_all_tasks" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="view_comments" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="add_comments" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="edit_comments" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="edit_own_comments" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="delete_comments" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="create_attachments" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="delete_attachments" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="view_history" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="close_own_tasks" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="close_other_tasks" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="assign_to_self" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="assign_others_to_self" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="add_to_assignees" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="view_reports" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="add_votes" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="edit_assignments" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="show_as_assignees" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="group_open" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="group_name">
+ <UNIQUE/>
+ <col>group_name</col>
+ <col>project_id</col>
+ </index>
+ <index name="belongs_to_project">
+ <col>project_id</col>
+ </index>
+ </table>
+ <table name="cache">
+ <field name="id" type="I" size="6">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="type" type="C" size="4">
+ <NOTNULL/>
+ </field>
+ <field name="content" type="XL">
+ <NOTNULL/>
+ </field>
+ <field name="topic" type="C" size="30">
+ <NOTNULL/>
+ </field>
+ <field name="last_updated" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="project_id" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="max_items" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="cache_type">
+ <UNIQUE/>
+ <col>type</col>
+ <col>topic</col>
+ <col>project_id</col>
+ <col>max_items</col>
+ </index>
+ <index name="cache_type_topic">
+ <col>type</col>
+ <col>topic</col>
+ </index>
+ </table>
+ <table name="admin_requests">
+ <field name="request_id" type="I" size="5">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="project_id" type="I" size="5">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="task_id" type="I" size="5">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="submitted_by" type="I" size="5">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="request_type" type="I" size="2">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="reason_given" type="X">
+ <NOTNULL/>
+ </field>
+ <field name="time_submitted" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="resolved_by" type="I" size="5">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="time_resolved" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="deny_reason" type="C" size="255" />
+ </table>
+</schema>
diff --git a/setup/upgrade/0.9.9.5/flyspray-install.xml b/setup/upgrade/0.9.9.5/flyspray-install.xml
new file mode 100644
index 0000000..11dc5ff
--- /dev/null
+++ b/setup/upgrade/0.9.9.5/flyspray-install.xml
@@ -0,0 +1,1058 @@
+<?xml version="1.0"?>
+<schema version="0.3">
+ <table name="admin_requests">
+ <field name="request_id" type="I" size="5">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="project_id" type="I" size="5">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="task_id" type="I" size="5">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="submitted_by" type="I" size="5">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="request_type" type="I" size="2">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="reason_given" type="X">
+ <NOTNULL/>
+ </field>
+ <field name="time_submitted" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="resolved_by" type="I" size="5">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="time_resolved" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="deny_reason" type="C" size="255" />
+ </table>
+ <table name="assigned">
+ <field name="assigned_id" type="I" size="10">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="task_id" type="I" size="10">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="user_id" type="I" size="5">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="task_user">
+ <UNIQUE/>
+ <col>task_id</col>
+ <col>user_id</col>
+ </index>
+ <index name="task_id_assigned">
+ <col>task_id</col>
+ <col>user_id</col>
+ </index>
+ </table>
+ <table name="attachments">
+ <field name="attachment_id" type="I" size="5">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="task_id" type="I" size="10">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="comment_id" type="I" size="10">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="orig_name" type="C" size="255">
+ <NOTNULL/>
+ </field>
+ <field name="file_name" type="C" size="30">
+ <NOTNULL/>
+ </field>
+ <field name="file_type" type="C" size="255">
+ <NOTNULL/>
+ </field>
+ <field name="file_size" type="I" size="20">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="added_by" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="date_added" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="task_id_attachments">
+ <col>task_id</col>
+ <col>comment_id</col>
+ </index>
+ </table>
+ <table name="cache">
+ <field name="id" type="I" size="6">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="type" type="C" size="4">
+ <NOTNULL/>
+ </field>
+ <field name="content" type="XL">
+ <NOTNULL/>
+ </field>
+ <field name="topic" type="I" size="11">
+ <NOTNULL/>
+ </field>
+ <field name="last_updated" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="project_id" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="max_items" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="cache_type">
+ <UNIQUE/>
+ <col>type</col>
+ <col>topic</col>
+ <col>project_id</col>
+ <col>max_items</col>
+ </index>
+ <index name="cache_type_topic">
+ <col>type</col>
+ <col>topic</col>
+ </index>
+ </table>
+ <table name="comments">
+ <field name="comment_id" type="I" size="10">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="task_id" type="I" size="10">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="date_added" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="user_id" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="comment_text" type="X">
+ <NOTNULL/>
+ </field>
+ <field name="last_edited_time" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="task_id_comments">
+ <col>task_id</col>
+ </index>
+ </table>
+ <table name="dependencies">
+ <field name="depend_id" type="I" size="10">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="task_id" type="I" size="10">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="dep_task_id" type="I" size="10">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="task_id_deps">
+ <UNIQUE/>
+ <col>task_id</col>
+ <col>dep_task_id</col>
+ </index>
+ </table>
+ <table name="groups">
+ <field name="group_id" type="I" size="3">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="group_name" type="C" size="20">
+ <NOTNULL/>
+ </field>
+ <field name="group_desc" type="C" size="150">
+ <NOTNULL/>
+ </field>
+ <field name="project_id" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="is_admin" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="manage_project" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="view_tasks" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="open_new_tasks" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="modify_own_tasks" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="modify_all_tasks" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="view_comments" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="add_comments" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="edit_comments" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="edit_own_comments" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="delete_comments" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="create_attachments" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="delete_attachments" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="view_history" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="close_own_tasks" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="close_other_tasks" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="assign_to_self" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="assign_others_to_self" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="add_to_assignees" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="view_reports" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="add_votes" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="edit_assignments" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="show_as_assignees" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="group_open" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="group_name">
+ <UNIQUE/>
+ <col>group_name</col>
+ <col>project_id</col>
+ </index>
+ <index name="belongs_to_project">
+ <col>project_id</col>
+ </index>
+ </table>
+ <table name="history">
+ <field name="history_id" type="I" size="10">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="task_id" type="I" size="10">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="user_id" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="event_date" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="event_type" type="I" size="2">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="field_changed" type="C" size="50">
+ <NOTNULL/>
+ </field>
+ <field name="old_value" type="X" />
+ <field name="new_value" type="X" />
+ <index name="idx_task_id">
+ <col>task_id</col>
+ </index>
+ </table>
+ <table name="list_category">
+ <field name="category_id" type="I" size="3">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="project_id" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="category_name" type="C" size="30">
+ <NOTNULL/>
+ </field>
+ <field name="show_in_list" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="category_owner" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="lft" type="I" size="10">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ <UNSIGNED/>
+ </field>
+ <field name="rgt" type="I" size="10">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ <UNSIGNED/>
+ </field>
+ <index name="project_id_cat">
+ <col>project_id</col>
+ </index>
+ </table>
+ <table name="list_os">
+ <field name="os_id" type="I" size="3">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="project_id" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="os_name" type="C" size="40">
+ <NOTNULL/>
+ </field>
+ <field name="list_position" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="show_in_list" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="project_id_os">
+ <col>project_id</col>
+ </index>
+ </table>
+ <table name="list_resolution">
+ <field name="resolution_id" type="I" size="3">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="resolution_name" type="C" size="30">
+ <NOTNULL/>
+ </field>
+ <field name="list_position" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="show_in_list" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="project_id" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="project_id_res">
+ <col>project_id</col>
+ </index>
+ </table>
+ <table name="list_status">
+ <field name="status_id" type="I" size="3">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="status_name" type="C" size="40">
+ <NOTNULL/>
+ </field>
+ <field name="list_position" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="show_in_list" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="project_id" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="project_id_status">
+ <col>project_id</col>
+ </index>
+ </table>
+ <table name="list_tasktype">
+ <field name="tasktype_id" type="I" size="3">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="tasktype_name" type="C" size="40">
+ <NOTNULL/>
+ </field>
+ <field name="list_position" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="show_in_list" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="project_id" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="project_id_tt">
+ <col>project_id</col>
+ </index>
+ </table>
+ <table name="list_version">
+ <field name="version_id" type="I" size="3">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="project_id" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="version_name" type="C" size="40">
+ <NOTNULL/>
+ </field>
+ <field name="list_position" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="show_in_list" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="version_tense" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="project_id_version">
+ <col>project_id</col>
+ <col>version_tense</col>
+ </index>
+ </table>
+ <table name="notification_messages">
+ <field name="message_id" type="I" size="10">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="message_subject" type="X">
+ <NOTNULL/>
+ </field>
+ <field name="message_body" type="X">
+ <NOTNULL/>
+ </field>
+ <field name="time_created" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ </table>
+ <table name="notification_recipients">
+ <field name="recipient_id" type="I" size="10">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="message_id" type="I" size="10">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="notify_method" type="C" size="1">
+ <NOTNULL/>
+ </field>
+ <field name="notify_address" type="C" size="100">
+ <NOTNULL/>
+ </field>
+ </table>
+ <table name="notifications">
+ <field name="notify_id" type="I" size="10">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="task_id" type="I" size="10">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="user_id" type="I" size="5">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="task_id_notifs">
+ <UNIQUE/>
+ <col>task_id</col>
+ <col>user_id</col>
+ </index>
+ </table>
+ <table name="prefs">
+ <field name="pref_id" type="I" size="1">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="pref_name" type="C" size="20">
+ <NOTNULL/>
+ </field>
+ <field name="pref_value" type="C" size="250">
+ <DEFAULT value="0"/>
+ <NOTNULL/>
+ </field>
+ </table>
+ <table name="projects">
+ <field name="project_id" type="I" size="3">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="project_title" type="C" size="100">
+ <NOTNULL/>
+ </field>
+ <field name="theme_style" type="C" size="20">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="default_cat_owner" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="intro_message" type="X">
+ <NOTNULL/>
+ <DEFAULT value=""/>
+ </field>
+ <field name="project_is_active" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="visible_columns" type="C" size="255">
+ <NOTNULL/>
+ </field>
+ <field name="others_view" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="anon_open" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="notify_email" type="X">
+ <NOTNULL/>
+ <DEFAULT value=""/>
+ </field>
+ <field name="notify_jabber" type="X">
+ <NOTNULL/>
+ <DEFAULT value=""/>
+ </field>
+ <field name="notify_reply" type="X">
+ <NOTNULL/>
+ <DEFAULT value=""/>
+ </field>
+ <field name="notify_types" type="C" size="100">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="feed_img_url" type="X">
+ <NOTNULL/>
+ <DEFAULT value=""/>
+ </field>
+ <field name="feed_description" type="X">
+ <NOTNULL/>
+ <DEFAULT value=""/>
+ </field>
+ <field name="notify_subject" type="C" size="100">
+ <NOTNULL/>
+ <DEFAULT value=""/>
+ </field>
+ <field name="lang_code" type="C" size="10">
+ <NOTNULL/>
+ </field>
+ <field name="comment_closed" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="auto_assign" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="last_updated" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="default_task" type="X">
+ <NOTNULL/>
+ </field>
+ <field name="default_entry" type="C" size="8">
+ <NOTNULL/>
+ <DEFAULT value="index"/>
+ </field>
+ </table>
+ <table name="registrations">
+ <field name="reg_id" type="I" size="10">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="reg_time" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="confirm_code" type="C" size="20">
+ <NOTNULL/>
+ </field>
+ <field name="user_name" type="C" size="32">
+ <NOTNULL/>
+ </field>
+ <field name="real_name" type="C" size="100">
+ <NOTNULL/>
+ </field>
+ <field name="email_address" type="C" size="100">
+ <NOTNULL/>
+ </field>
+ <field name="jabber_id" type="C" size="100">
+ <NOTNULL/>
+ </field>
+ <field name="notify_type" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="magic_url" type="C" size="40">
+ <NOTNULL/>
+ </field>
+ <field name="time_zone" type="I" size="6">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ </table>
+ <table name="related">
+ <field name="related_id" type="I" size="10">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="this_task" type="I" size="10">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="related_task" type="I" size="10">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="is_duplicate" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="this_task">
+ <UNIQUE/>
+ <col>this_task</col>
+ <col>related_task</col>
+ <col>is_duplicate</col>
+ </index>
+ </table>
+ <table name="reminders">
+ <field name="reminder_id" type="I" size="10">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="task_id" type="I" size="10">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="to_user_id" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="from_user_id" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="start_time" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="how_often" type="I" size="12">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="last_sent" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="reminder_message" type="X">
+ <NOTNULL/>
+ </field>
+ </table>
+ <table name="searches">
+ <field name="id" type="I" size="11">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="user_id" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="name" type="C" size="50">
+ <NOTNULL/>
+ </field>
+ <field name="search_string" type="X">
+ <NOTNULL/>
+ </field>
+ <field name="time" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ </table>
+ <table name="tasks">
+ <field name="task_id" type="I" size="10">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="project_id" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="task_type" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="date_opened" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="opened_by" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="is_closed" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="date_closed" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="closed_by" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="closure_comment" type="X">
+ <NOTNULL/>
+ </field>
+ <field name="item_summary" type="C" size="100">
+ <NOTNULL/>
+ </field>
+ <field name="detailed_desc" type="X">
+ <NOTNULL/>
+ </field>
+ <field name="item_status" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="resolution_reason" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="1"/>
+ </field>
+ <field name="product_category" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="product_version" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="closedby_version" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="operating_system" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="task_severity" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="task_priority" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="last_edited_by" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="last_edited_time" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="percent_complete" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="mark_private" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="due_date" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="anon_email" type="C" size="100">
+ <NOTNULL/>
+ <DEFAULT value=""/>
+ </field>
+ <field name="task_token" type="C" size="32">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="attached_to_project">
+ <col>project_id</col>
+ </index>
+ <index name="task_severity">
+ <col>task_severity</col>
+ </index>
+ <index name="task_type">
+ <col>task_type</col>
+ </index>
+ <index name="product_category">
+ <col>product_category</col>
+ </index>
+ <index name="item_status">
+ <col>item_status</col>
+ </index>
+ <index name="is_closed">
+ <col>is_closed</col>
+ </index>
+ <index name="closedby_version">
+ <col>closedby_version</col>
+ </index>
+ <index name="due_date">
+ <col>due_date</col>
+ </index>
+ </table>
+ <table name="users">
+ <field name="user_id" type="I" size="3">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="user_name" type="C" size="32">
+ <NOTNULL/>
+ </field>
+ <field name="user_pass" type="C" size="40"/>
+ <field name="real_name" type="C" size="100">
+ <NOTNULL/>
+ </field>
+ <field name="jabber_id" type="C" size="100">
+ <NOTNULL/>
+ </field>
+ <field name="email_address" type="C" size="100">
+ <NOTNULL/>
+ </field>
+ <field name="notify_type" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="notify_own" type="I" size="6">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="account_enabled" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="dateformat" type="C" size="30">
+ <NOTNULL/>
+ <DEFAULT value=""/>
+ </field>
+ <field name="dateformat_extended" type="C" size="30">
+ <NOTNULL/>
+ <DEFAULT value=""/>
+ </field>
+ <field name="magic_url" type="C" size="40">
+ <NOTNULL/>
+ <DEFAULT value=""/>
+ </field>
+ <field name="tasks_perpage" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="register_date" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="time_zone" type="I" size="6">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="login_attempts" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="lock_until" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="user_name">
+ <UNIQUE/>
+ <col>user_name</col>
+ </index>
+ </table>
+ <table name="users_in_groups">
+ <field name="record_id" type="I" size="5">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="user_id" type="I" size="5">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="group_id" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="group_id_uig">
+ <UNIQUE/>
+ <col>group_id</col>
+ <col>user_id</col>
+ </index>
+ <index name="user_id_uig">
+ <col>user_id</col>
+ </index>
+ </table>
+ <table name="votes">
+ <field name="vote_id" type="I" size="11">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="user_id" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="task_id" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="date_time" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="task_id_votes">
+ <col>task_id</col>
+ </index>
+ </table>
+ <sql>
+ <query>INSERT INTO groups VALUES (DEFAULT, 'Admin', 'Members have unlimited access to all functionality.', 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0,1, 1);</query>
+ <query>INSERT INTO groups VALUES (DEFAULT, 'Developers', 'Global Developers for all projects', 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1,1, 1);</query>
+ <query>INSERT INTO groups VALUES (DEFAULT, 'Reporters', 'Open new tasks / add comments in all projects', 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1);</query>
+ <query>INSERT INTO groups VALUES (DEFAULT, 'Basic', 'Members can login, relying upon Project permissions only', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,0, 1);</query>
+ <query>INSERT INTO groups VALUES (DEFAULT, 'Pending', 'Users who are awaiting approval of their accounts.', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);</query>
+ <query>INSERT INTO groups VALUES (DEFAULT, 'Project Managers', 'Permission to do anything related to the Default Project.', 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1);</query>
+ <query>INSERT INTO history VALUES (DEFAULT, 1, 1, 1130024797, 1, '', '', '');</query>
+ <query>INSERT INTO list_category VALUES (DEFAULT, 1, 'Backend / Core', 1, 0, 2, 3);</query>
+ <query>INSERT INTO list_category VALUES (DEFAULT, 0, 'root', 0, 0, 1, 2);</query>
+ <query>INSERT INTO list_category VALUES (DEFAULT, 1, 'root', 0, 0, 1, 4);</query>
+ <query>INSERT INTO list_os VALUES (DEFAULT, 1, 'All', 1, 1);</query>
+ <query>INSERT INTO list_os VALUES (DEFAULT, 1, 'Windows', 2, 1);</query>
+ <query>INSERT INTO list_os VALUES (DEFAULT, 1, 'Linux', 3, 1);</query>
+ <query>INSERT INTO list_os VALUES (DEFAULT, 1, 'Mac OS', 4, 1);</query>
+ <query>INSERT INTO list_resolution VALUES (DEFAULT, 'Not a bug', 1, 1, 0);</query>
+ <query>INSERT INTO list_resolution VALUES (DEFAULT, 'Won''t fix', 2, 1, 0);</query>
+ <query>INSERT INTO list_resolution VALUES (DEFAULT, 'Won''t implement', 3, 1, 0);</query>
+ <query>INSERT INTO list_resolution VALUES (DEFAULT, 'Works for me', 4, 1, 0);</query>
+ <query>INSERT INTO list_resolution VALUES (DEFAULT, 'Deferred', 5, 1, 0);</query>
+ <query>INSERT INTO list_resolution VALUES (DEFAULT, 'Duplicate', 6, 1, 0);</query>
+ <query>INSERT INTO list_resolution VALUES (DEFAULT, 'Fixed', 7, 1, 0);</query>
+ <query>INSERT INTO list_resolution VALUES (DEFAULT, 'Implemented', 8, 1, 0);</query>
+ <query>INSERT INTO list_tasktype VALUES (DEFAULT, 'Bug Report', 1, 1, 0);</query>
+ <query>INSERT INTO list_tasktype VALUES (DEFAULT, 'Feature Request', 2, 1, 0);</query>
+ <query>INSERT INTO list_version VALUES (DEFAULT, 1, 'Development', 1, 1, 2);</query>
+ <query>INSERT INTO list_status (status_name, list_position, show_in_list, project_id) VALUES ('Unconfirmed', 1, 1, 0)</query>
+ <query>INSERT INTO list_status (status_name, list_position, show_in_list, project_id) VALUES ('New', 2, 1, 0)</query>
+ <query>INSERT INTO list_status (status_name, list_position, show_in_list, project_id) VALUES ('Assigned', 3, 1, 0)</query>
+ <query>INSERT INTO list_status (status_name, list_position, show_in_list, project_id) VALUES ('Researching', 4, 1, 0)</query>
+ <query>INSERT INTO list_status (status_name, list_position, show_in_list, project_id) VALUES ('Waiting on Customer', 5, 1, 0)</query>
+ <query>INSERT INTO list_status (status_name, list_position, show_in_list, project_id) VALUES ('Requires testing', 6, 1, 0)</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'fs_ver', '0.9.9');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'jabber_server', '');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'jabber_port', '5222');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'jabber_username', '');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'jabber_password', '');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'anon_group', '4');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'user_notify', '1');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'admin_email', 'flyspray@example.com');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'lang_code', 'en');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'spam_proof', '1');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'default_project', '1');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'dateformat', '');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'dateformat_extended', '');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'anon_reg', '1');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'global_theme', 'CleanFS');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'visible_columns', 'id project category tasktype severity summary status progress');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'smtp_server', '');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'smtp_user', '');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'smtp_pass', '');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'page_title', 'Flyspray::');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'notify_registration', '0');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'jabber_ssl', '0');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'last_update_check', '0');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'cache_feeds', '1');</query>
+ <query>INSERT INTO projects VALUES (DEFAULT, 'Default Project', 'CleanFS', 0, 'Welcome to your first Flyspray project! We hope that Flyspray provides you with many hours of increased productivity. If you have any issues, go to http://flyspray.org/support. You can customise this message by clicking the **Manage Project** link in the menu above...', 1, 'id category tasktype severity summary status progress', 1, 0, '', '', NULL, '0', NULL, NULL, '', 'en', 0, 0, 0, NULL, 'index');</query>
+ <query>INSERT INTO tasks VALUES (1, 1, 1, 1130024797, 1, 0, 0, 0, ' ', 'Sample Task', 'This isn''t a real task. You should close it and start opening some real tasks.', 2, 1, 1, 1, 0, 1, 1, 2, 0, 0, 0, 0, 0, '', '0');</query>
+ <query>INSERT INTO users VALUES (DEFAULT, 'super', '1b3231655cebb7a1f783eddf27d254ca', 'Mr Super User', 'super@example.com', 'super@example.com', 0, 1, 1, '', '', 25, 0, 0, 0, 0, 0);</query>
+ <query>INSERT INTO users_in_groups VALUES (DEFAULT, 1, 1);</query>
+ </sql>
+</schema>
diff --git a/setup/upgrade/0.9.9.5/upgrade.info b/setup/upgrade/0.9.9.5/upgrade.info
new file mode 100644
index 0000000..68f3208
--- /dev/null
+++ b/setup/upgrade/0.9.9.5/upgrade.info
@@ -0,0 +1,34 @@
+[defaultupgrade]
+1="upgrade.xml"
+
+[develupgrade]
+1="upgrade.xml"
+
+[fsprefs]
+fs_ver="0.9.7" ; doesn't matter which version
+jabber_server=""
+jabber_port="5222"
+jabber_username=""
+jabber_password=""
+anon_group="0"
+user_notify="1"
+admin_email="flyspray@example.com"
+lang_code="en"
+spam_proof="1"
+default_project="1"
+dateformat=""
+dateformat_extended=""
+anon_reg="1"
+page_title="Flyspray:: "
+notify_registration="0"
+jabber_ssl="0"
+last_update_check="0"
+cache_feeds="1"
+global_theme="CleanFS"
+visible_columns="id project tasktype severity summary status progress"
+smtp_server=""
+smtp_user=""
+smtp_pass=""
+lock_for="5"
+email_ssl="0"
+email_tls="0" \ No newline at end of file
diff --git a/setup/upgrade/0.9.9.5/upgrade.xml b/setup/upgrade/0.9.9.5/upgrade.xml
new file mode 100644
index 0000000..f11b3c8
--- /dev/null
+++ b/setup/upgrade/0.9.9.5/upgrade.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0"?>
+<schema version="0.3">
+ <table name="cache">
+ <field name="id" type="I" size="6">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="type" type="C" size="4">
+ <NOTNULL/>
+ </field>
+ <field name="content" type="XL">
+ <NOTNULL/>
+ </field>
+ <field name="topic" type="I" size="11">
+ <NOTNULL/>
+ </field>
+ <field name="last_updated" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="project_id" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="max_items" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="cache_type">
+ <UNIQUE/>
+ <col>type</col>
+ <col>topic</col>
+ <col>project_id</col>
+ <col>max_items</col>
+ </index>
+ <index name="cache_type_topic">
+ <col>type</col>
+ <col>topic</col>
+ </index>
+ </table>
+</schema> \ No newline at end of file
diff --git a/setup/upgrade/0.9.9.7/flyspray-install.xml b/setup/upgrade/0.9.9.7/flyspray-install.xml
new file mode 100644
index 0000000..10c79d1
--- /dev/null
+++ b/setup/upgrade/0.9.9.7/flyspray-install.xml
@@ -0,0 +1,1059 @@
+<?xml version="1.0"?>
+<schema version="0.3">
+ <table name="admin_requests">
+ <field name="request_id" type="I" size="5">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="project_id" type="I" size="5">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="task_id" type="I" size="5">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="submitted_by" type="I" size="5">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="request_type" type="I" size="2">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="reason_given" type="X">
+ <NOTNULL/>
+ </field>
+ <field name="time_submitted" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="resolved_by" type="I" size="5">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="time_resolved" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="deny_reason" type="C" size="255" />
+ </table>
+ <table name="assigned">
+ <field name="assigned_id" type="I" size="10">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="task_id" type="I" size="10">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="user_id" type="I" size="5">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="task_user">
+ <UNIQUE/>
+ <col>task_id</col>
+ <col>user_id</col>
+ </index>
+ <index name="task_id_assigned">
+ <col>task_id</col>
+ <col>user_id</col>
+ </index>
+ </table>
+ <table name="attachments">
+ <field name="attachment_id" type="I" size="5">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="task_id" type="I" size="10">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="comment_id" type="I" size="10">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="orig_name" type="C" size="255">
+ <NOTNULL/>
+ </field>
+ <field name="file_name" type="C" size="30">
+ <NOTNULL/>
+ </field>
+ <field name="file_type" type="C" size="255">
+ <NOTNULL/>
+ </field>
+ <field name="file_size" type="I" size="20">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="added_by" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="date_added" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="task_id_attachments">
+ <col>task_id</col>
+ <col>comment_id</col>
+ </index>
+ </table>
+ <table name="cache">
+ <field name="id" type="I" size="6">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="type" type="C" size="4">
+ <NOTNULL/>
+ </field>
+ <field name="content" type="XL">
+ <NOTNULL/>
+ </field>
+ <field name="topic" type="I" size="11">
+ <NOTNULL/>
+ </field>
+ <field name="last_updated" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="project_id" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="max_items" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="cache_type">
+ <UNIQUE/>
+ <col>type</col>
+ <col>topic</col>
+ <col>project_id</col>
+ <col>max_items</col>
+ </index>
+ <index name="cache_type_topic">
+ <col>type</col>
+ <col>topic</col>
+ </index>
+ </table>
+ <table name="comments">
+ <field name="comment_id" type="I" size="10">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="task_id" type="I" size="10">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="date_added" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="user_id" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="comment_text" type="X">
+ <NOTNULL/>
+ </field>
+ <field name="last_edited_time" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="task_id_comments">
+ <col>task_id</col>
+ </index>
+ </table>
+ <table name="dependencies">
+ <field name="depend_id" type="I" size="10">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="task_id" type="I" size="10">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="dep_task_id" type="I" size="10">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="task_id_deps">
+ <UNIQUE/>
+ <col>task_id</col>
+ <col>dep_task_id</col>
+ </index>
+ </table>
+ <table name="groups">
+ <field name="group_id" type="I" size="3">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="group_name" type="C" size="20">
+ <NOTNULL/>
+ </field>
+ <field name="group_desc" type="C" size="150">
+ <NOTNULL/>
+ </field>
+ <field name="project_id" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="is_admin" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="manage_project" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="view_tasks" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="open_new_tasks" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="modify_own_tasks" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="modify_all_tasks" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="view_comments" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="add_comments" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="edit_comments" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="edit_own_comments" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="delete_comments" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="create_attachments" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="delete_attachments" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="view_history" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="close_own_tasks" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="close_other_tasks" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="assign_to_self" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="assign_others_to_self" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="add_to_assignees" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="view_reports" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="add_votes" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="edit_assignments" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="show_as_assignees" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="group_open" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="group_name">
+ <UNIQUE/>
+ <col>group_name</col>
+ <col>project_id</col>
+ </index>
+ <index name="belongs_to_project">
+ <col>project_id</col>
+ </index>
+ </table>
+ <table name="history">
+ <field name="history_id" type="I" size="10">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="task_id" type="I" size="10">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="user_id" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="event_date" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="event_type" type="I" size="2">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="field_changed" type="C" size="50">
+ <NOTNULL/>
+ </field>
+ <field name="old_value" type="X" />
+ <field name="new_value" type="X" />
+ <index name="idx_task_id">
+ <col>task_id</col>
+ </index>
+ </table>
+ <table name="list_category">
+ <field name="category_id" type="I" size="3">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="project_id" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="category_name" type="C" size="30">
+ <NOTNULL/>
+ </field>
+ <field name="show_in_list" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="category_owner" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="lft" type="I" size="10">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ <UNSIGNED/>
+ </field>
+ <field name="rgt" type="I" size="10">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ <UNSIGNED/>
+ </field>
+ <index name="project_id_cat">
+ <col>project_id</col>
+ </index>
+ </table>
+ <table name="list_os">
+ <field name="os_id" type="I" size="3">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="project_id" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="os_name" type="C" size="40">
+ <NOTNULL/>
+ </field>
+ <field name="list_position" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="show_in_list" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="project_id_os">
+ <col>project_id</col>
+ </index>
+ </table>
+ <table name="list_resolution">
+ <field name="resolution_id" type="I" size="3">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="resolution_name" type="C" size="30">
+ <NOTNULL/>
+ </field>
+ <field name="list_position" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="show_in_list" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="project_id" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="project_id_res">
+ <col>project_id</col>
+ </index>
+ </table>
+ <table name="list_status">
+ <field name="status_id" type="I" size="3">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="status_name" type="C" size="40">
+ <NOTNULL/>
+ </field>
+ <field name="list_position" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="show_in_list" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="project_id" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="project_id_status">
+ <col>project_id</col>
+ </index>
+ </table>
+ <table name="list_tasktype">
+ <field name="tasktype_id" type="I" size="3">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="tasktype_name" type="C" size="40">
+ <NOTNULL/>
+ </field>
+ <field name="list_position" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="show_in_list" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="project_id" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="project_id_tt">
+ <col>project_id</col>
+ </index>
+ </table>
+ <table name="list_version">
+ <field name="version_id" type="I" size="3">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="project_id" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="version_name" type="C" size="40">
+ <NOTNULL/>
+ </field>
+ <field name="list_position" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="show_in_list" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="version_tense" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="project_id_version">
+ <col>project_id</col>
+ <col>version_tense</col>
+ </index>
+ </table>
+ <table name="notification_messages">
+ <field name="message_id" type="I" size="10">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="message_subject" type="X">
+ <NOTNULL/>
+ </field>
+ <field name="message_body" type="X">
+ <NOTNULL/>
+ </field>
+ <field name="time_created" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ </table>
+ <table name="notification_recipients">
+ <field name="recipient_id" type="I" size="10">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="message_id" type="I" size="10">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="notify_method" type="C" size="1">
+ <NOTNULL/>
+ </field>
+ <field name="notify_address" type="C" size="100">
+ <NOTNULL/>
+ </field>
+ </table>
+ <table name="notifications">
+ <field name="notify_id" type="I" size="10">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="task_id" type="I" size="10">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="user_id" type="I" size="5">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="task_id_notifs">
+ <UNIQUE/>
+ <col>task_id</col>
+ <col>user_id</col>
+ </index>
+ </table>
+ <table name="prefs">
+ <field name="pref_id" type="I" size="1">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="pref_name" type="C" size="20">
+ <NOTNULL/>
+ </field>
+ <field name="pref_value" type="C" size="250">
+ <DEFAULT value="0"/>
+ <NOTNULL/>
+ </field>
+ </table>
+ <table name="projects">
+ <field name="project_id" type="I" size="3">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="project_title" type="C" size="100">
+ <NOTNULL/>
+ </field>
+ <field name="theme_style" type="C" size="20">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="default_cat_owner" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="intro_message" type="X">
+ <NOTNULL/>
+ <DEFAULT value=""/>
+ </field>
+ <field name="project_is_active" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="visible_columns" type="C" size="255">
+ <NOTNULL/>
+ </field>
+ <field name="others_view" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="anon_open" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="notify_email" type="X">
+ <NOTNULL/>
+ <DEFAULT value=""/>
+ </field>
+ <field name="notify_jabber" type="X">
+ <NOTNULL/>
+ <DEFAULT value=""/>
+ </field>
+ <field name="notify_reply" type="X">
+ <NOTNULL/>
+ <DEFAULT value=""/>
+ </field>
+ <field name="notify_types" type="C" size="100">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="feed_img_url" type="X">
+ <NOTNULL/>
+ <DEFAULT value=""/>
+ </field>
+ <field name="feed_description" type="X">
+ <NOTNULL/>
+ <DEFAULT value=""/>
+ </field>
+ <field name="notify_subject" type="C" size="100">
+ <NOTNULL/>
+ <DEFAULT value=""/>
+ </field>
+ <field name="lang_code" type="C" size="10">
+ <NOTNULL/>
+ </field>
+ <field name="comment_closed" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="auto_assign" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="last_updated" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="default_task" type="X">
+ <NOTNULL/>
+ </field>
+ <field name="default_entry" type="C" size="8">
+ <NOTNULL/>
+ <DEFAULT value="index"/>
+ </field>
+ </table>
+ <table name="registrations">
+ <field name="reg_id" type="I" size="10">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="reg_time" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="confirm_code" type="C" size="20">
+ <NOTNULL/>
+ </field>
+ <field name="user_name" type="C" size="32">
+ <NOTNULL/>
+ </field>
+ <field name="real_name" type="C" size="100">
+ <NOTNULL/>
+ </field>
+ <field name="email_address" type="C" size="100">
+ <NOTNULL/>
+ </field>
+ <field name="jabber_id" type="C" size="100">
+ <NOTNULL/>
+ </field>
+ <field name="notify_type" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="magic_url" type="C" size="40">
+ <NOTNULL/>
+ </field>
+ <field name="time_zone" type="I" size="6">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ </table>
+ <table name="related">
+ <field name="related_id" type="I" size="10">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="this_task" type="I" size="10">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="related_task" type="I" size="10">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="is_duplicate" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="this_task">
+ <UNIQUE/>
+ <col>this_task</col>
+ <col>related_task</col>
+ <col>is_duplicate</col>
+ </index>
+ </table>
+ <table name="reminders">
+ <field name="reminder_id" type="I" size="10">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="task_id" type="I" size="10">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="to_user_id" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="from_user_id" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="start_time" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="how_often" type="I" size="12">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="last_sent" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="reminder_message" type="X">
+ <NOTNULL/>
+ </field>
+ </table>
+ <table name="searches">
+ <field name="id" type="I" size="11">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="user_id" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="name" type="C" size="50">
+ <NOTNULL/>
+ </field>
+ <field name="search_string" type="X">
+ <NOTNULL/>
+ </field>
+ <field name="time" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ </table>
+ <table name="tasks">
+ <field name="task_id" type="I" size="10">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="project_id" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="task_type" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="date_opened" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="opened_by" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="is_closed" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="date_closed" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="closed_by" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="closure_comment" type="X">
+ <NOTNULL/>
+ </field>
+ <field name="item_summary" type="C" size="100">
+ <NOTNULL/>
+ </field>
+ <field name="detailed_desc" type="X">
+ <NOTNULL/>
+ </field>
+ <field name="item_status" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="resolution_reason" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="1"/>
+ </field>
+ <field name="product_category" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="product_version" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="closedby_version" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="operating_system" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="task_severity" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="task_priority" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="last_edited_by" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="last_edited_time" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="percent_complete" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="mark_private" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="due_date" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="anon_email" type="C" size="100">
+ <NOTNULL/>
+ <DEFAULT value=""/>
+ </field>
+ <field name="task_token" type="C" size="32">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="attached_to_project">
+ <col>project_id</col>
+ </index>
+ <index name="task_severity">
+ <col>task_severity</col>
+ </index>
+ <index name="task_type">
+ <col>task_type</col>
+ </index>
+ <index name="product_category">
+ <col>product_category</col>
+ </index>
+ <index name="item_status">
+ <col>item_status</col>
+ </index>
+ <index name="is_closed">
+ <col>is_closed</col>
+ </index>
+ <index name="closedby_version">
+ <col>closedby_version</col>
+ </index>
+ <index name="due_date">
+ <col>due_date</col>
+ </index>
+ </table>
+ <table name="users">
+ <field name="user_id" type="I" size="3">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="user_name" type="C" size="32">
+ <NOTNULL/>
+ </field>
+ <field name="user_pass" type="C" size="40"/>
+ <field name="real_name" type="C" size="100">
+ <NOTNULL/>
+ </field>
+ <field name="jabber_id" type="C" size="100">
+ <NOTNULL/>
+ </field>
+ <field name="email_address" type="C" size="100">
+ <NOTNULL/>
+ </field>
+ <field name="notify_type" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="notify_own" type="I" size="6">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="account_enabled" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="dateformat" type="C" size="30">
+ <NOTNULL/>
+ <DEFAULT value=""/>
+ </field>
+ <field name="dateformat_extended" type="C" size="30">
+ <NOTNULL/>
+ <DEFAULT value=""/>
+ </field>
+ <field name="magic_url" type="C" size="40">
+ <NOTNULL/>
+ <DEFAULT value=""/>
+ </field>
+ <field name="tasks_perpage" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="register_date" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="time_zone" type="I" size="6">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="login_attempts" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="lock_until" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="user_name">
+ <UNIQUE/>
+ <col>user_name</col>
+ </index>
+ </table>
+ <table name="users_in_groups">
+ <field name="record_id" type="I" size="5">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="user_id" type="I" size="5">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="group_id" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="group_id_uig">
+ <UNIQUE/>
+ <col>group_id</col>
+ <col>user_id</col>
+ </index>
+ <index name="user_id_uig">
+ <col>user_id</col>
+ </index>
+ </table>
+ <table name="votes">
+ <field name="vote_id" type="I" size="11">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="user_id" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="task_id" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="date_time" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="task_id_votes">
+ <col>task_id</col>
+ </index>
+ </table>
+ <sql>
+ <query>INSERT INTO groups VALUES (DEFAULT, 'Admin', 'Members have unlimited access to all functionality.', 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0,1, 1);</query>
+ <query>INSERT INTO groups VALUES (DEFAULT, 'Developers', 'Global Developers for all projects', 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1,1, 1);</query>
+ <query>INSERT INTO groups VALUES (DEFAULT, 'Reporters', 'Open new tasks / add comments in all projects', 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1);</query>
+ <query>INSERT INTO groups VALUES (DEFAULT, 'Basic', 'Members can login, relying upon Project permissions only', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,0, 1);</query>
+ <query>INSERT INTO groups VALUES (DEFAULT, 'Pending', 'Users who are awaiting approval of their accounts.', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);</query>
+ <query>INSERT INTO groups VALUES (DEFAULT, 'Project Managers', 'Permission to do anything related to the Default Project.', 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1);</query>
+ <query>INSERT INTO history VALUES (DEFAULT, 1, 1, 1130024797, 1, '', '', '');</query>
+ <query>INSERT INTO list_category VALUES (DEFAULT, 1, 'Backend / Core', 1, 0, 2, 3);</query>
+ <query>INSERT INTO list_category VALUES (DEFAULT, 0, 'root', 0, 0, 1, 2);</query>
+ <query>INSERT INTO list_category VALUES (DEFAULT, 1, 'root', 0, 0, 1, 4);</query>
+ <query>INSERT INTO list_os VALUES (DEFAULT, 1, 'All', 1, 1);</query>
+ <query>INSERT INTO list_os VALUES (DEFAULT, 1, 'Windows', 2, 1);</query>
+ <query>INSERT INTO list_os VALUES (DEFAULT, 1, 'Linux', 3, 1);</query>
+ <query>INSERT INTO list_os VALUES (DEFAULT, 1, 'Mac OS', 4, 1);</query>
+ <query>INSERT INTO list_resolution VALUES (DEFAULT, 'Not a bug', 1, 1, 0);</query>
+ <query>INSERT INTO list_resolution VALUES (DEFAULT, 'Won''t fix', 2, 1, 0);</query>
+ <query>INSERT INTO list_resolution VALUES (DEFAULT, 'Won''t implement', 3, 1, 0);</query>
+ <query>INSERT INTO list_resolution VALUES (DEFAULT, 'Works for me', 4, 1, 0);</query>
+ <query>INSERT INTO list_resolution VALUES (DEFAULT, 'Deferred', 5, 1, 0);</query>
+ <query>INSERT INTO list_resolution VALUES (DEFAULT, 'Duplicate', 6, 1, 0);</query>
+ <query>INSERT INTO list_resolution VALUES (DEFAULT, 'Fixed', 7, 1, 0);</query>
+ <query>INSERT INTO list_resolution VALUES (DEFAULT, 'Implemented', 8, 1, 0);</query>
+ <query>INSERT INTO list_tasktype VALUES (DEFAULT, 'Bug Report', 1, 1, 0);</query>
+ <query>INSERT INTO list_tasktype VALUES (DEFAULT, 'Feature Request', 2, 1, 0);</query>
+ <query>INSERT INTO list_version VALUES (DEFAULT, 1, 'Development', 1, 1, 2);</query>
+ <query>INSERT INTO list_status (status_name, list_position, show_in_list, project_id) VALUES ('Unconfirmed', 1, 1, 0)</query>
+ <query>INSERT INTO list_status (status_name, list_position, show_in_list, project_id) VALUES ('New', 2, 1, 0)</query>
+ <query>INSERT INTO list_status (status_name, list_position, show_in_list, project_id) VALUES ('Assigned', 3, 1, 0)</query>
+ <query>INSERT INTO list_status (status_name, list_position, show_in_list, project_id) VALUES ('Researching', 4, 1, 0)</query>
+ <query>INSERT INTO list_status (status_name, list_position, show_in_list, project_id) VALUES ('Waiting on Customer', 5, 1, 0)</query>
+ <query>INSERT INTO list_status (status_name, list_position, show_in_list, project_id) VALUES ('Requires testing', 6, 1, 0)</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'fs_ver', '0.9.9');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'logo', '');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'jabber_server', '');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'jabber_port', '5222');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'jabber_username', '');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'jabber_password', '');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'anon_group', '4');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'user_notify', '1');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'admin_email', 'flyspray@example.com');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'lang_code', 'en');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'spam_proof', '1');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'default_project', '1');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'dateformat', '');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'dateformat_extended', '');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'anon_reg', '1');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'global_theme', 'CleanFS');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'visible_columns', 'id project category tasktype severity summary status progress');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'smtp_server', '');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'smtp_user', '');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'smtp_pass', '');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'page_title', 'Flyspray::');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'notify_registration', '0');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'jabber_ssl', '0');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'last_update_check', '0');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'cache_feeds', '1');</query>
+ <query>INSERT INTO projects VALUES (DEFAULT, 'Default Project', 'CleanFS', 0, 'Welcome to your first Flyspray project! We hope that Flyspray provides you with many hours of increased productivity. If you have any issues, go to http://flyspray.org/support. You can customise this message by clicking the **Manage Project** link in the menu above...', 1, 'id category tasktype severity summary status progress', 1, 0, '', '', NULL, '0', NULL, NULL, '', 'en', 0, 0, 0, NULL, 'index');</query>
+ <query>INSERT INTO tasks VALUES (1, 1, 1, 1130024797, 1, 0, 0, 0, ' ', 'Sample Task', 'This isn''t a real task. You should close it and start opening some real tasks.', 2, 1, 1, 1, 0, 1, 1, 2, 0, 0, 0, 0, 0, '', '0');</query>
+ <query>INSERT INTO users VALUES (DEFAULT, 'super', '1b3231655cebb7a1f783eddf27d254ca', 'Mr Super User', 'super@example.com', 'super@example.com', 0, 1, 1, '', '', 25, 0, 0, 0, 0, 0);</query>
+ <query>INSERT INTO users_in_groups VALUES (DEFAULT, 1, 1);</query>
+ </sql>
+</schema>
diff --git a/setup/upgrade/0.9.9.7/upgrade.info b/setup/upgrade/0.9.9.7/upgrade.info
new file mode 100644
index 0000000..324d70e
--- /dev/null
+++ b/setup/upgrade/0.9.9.7/upgrade.info
@@ -0,0 +1,35 @@
+[defaultupgrade]
+;1="upgrade.xml"
+
+[develupgrade]
+;1="upgrade.xml"
+
+[fsprefs]
+fs_ver="0.9.7" ; doesn't matter which version
+jabber_server=""
+jabber_port="5222"
+jabber_username=""
+jabber_password=""
+anon_group="0"
+user_notify="1"
+admin_email="flyspray@example.com"
+lang_code="en"
+spam_proof="1"
+default_project="1"
+dateformat=""
+dateformat_extended=""
+anon_reg="1"
+page_title="Flyspray:: "
+notify_registration="0"
+jabber_ssl="0"
+last_update_check="0"
+cache_feeds="1"
+global_theme="CleanFS"
+visible_columns="id project tasktype severity summary status progress"
+smtp_server=""
+smtp_user=""
+smtp_pass=""
+lock_for="5"
+email_ssl="0"
+email_tls="0"
+default_timezone="0" \ No newline at end of file
diff --git a/setup/upgrade/0.9.9/add_data.php b/setup/upgrade/0.9.9/add_data.php
new file mode 100644
index 0000000..8c32d38
--- /dev/null
+++ b/setup/upgrade/0.9.9/add_data.php
@@ -0,0 +1,34 @@
+<?php
+ /**********************************************************\
+ | This script adds/deletes data what can't be added to |
+ | the XML schema files. |
+ \***********************************************************/
+
+// New status list, make sure data is only inserted if we have an empty table
+$sql = $db->query('SELECT count(*) FROM {list_status}');
+if ($db->fetchOne($sql) < 1) {
+ $db->query("INSERT INTO {list_status} (status_name, list_position, show_in_list, project_id) VALUES ('Unconfirmed', 1, 1, 0)");
+ $db->query("INSERT INTO {list_status} (status_name, list_position, show_in_list, project_id) VALUES ('New', 2, 1, 0)");
+ $db->query("INSERT INTO {list_status} (status_name, list_position, show_in_list, project_id) VALUES ('Assigned', 3, 1, 0)");
+ $db->query("INSERT INTO {list_status} (status_name, list_position, show_in_list, project_id) VALUES ('Researching', 4, 1, 0)");
+ $db->query("INSERT INTO {list_status} (status_name, list_position, show_in_list, project_id) VALUES ('Waiting on Customer', 5, 1, 0)");
+ $db->query("INSERT INTO {list_status} (status_name, list_position, show_in_list, project_id) VALUES ('Requires testing', 6, 1, 0)");
+}
+
+if (Post::val('replace_resolution')) {
+ $db->query('UPDATE {list_resolution} SET resolution_name = ? WHERE resolution_id = ?', array('Duplicate (the real one)', 6));
+}
+
+$db->query("DELETE FROM {list_status} WHERE status_id = 7");
+$db->query("DELETE FROM {notifications} WHERE user_id = 0 OR task_id = 0");
+
+$db->query("UPDATE {tasks} SET closure_comment='' WHERE closure_comment='0'");
+$db->query("UPDATE {groups} SET add_to_assignees = '1' WHERE assign_others_to_self =1 ");
+$db->query("UPDATE {groups} SET add_votes = 1 WHERE group_id = 2 OR group_id = 3 OR group_id = 6");
+$db->query("UPDATE {groups} SET edit_assignments = '1' WHERE group_id = 2");
+$db->query("UPDATE {history} SET event_type = 3 WHERE event_type = 0");
+$db->query("UPDATE {history} SET event_type = 11 WHERE event_type = 15");
+$db->query("UPDATE {history} SET event_type = 12 WHERE event_type = 16");
+$db->query("UPDATE {history} SET field_changed = 'project_id' WHERE field_changed = 'attached_to_project'");
+
+?>
diff --git a/setup/upgrade/0.9.9/add_duplicates.php b/setup/upgrade/0.9.9/add_duplicates.php
new file mode 100644
index 0000000..4a00a8a
--- /dev/null
+++ b/setup/upgrade/0.9.9/add_duplicates.php
@@ -0,0 +1,41 @@
+<?php
+ /**********************************************************\
+ | This script enters the relations of duplicate tasks into |
+ | the databse. |
+ \***********************************************************/
+
+
+$check_sql = $db->query('SELECT task_id, closure_comment, resolution_reason FROM {tasks}');
+
+while ($row = $db->fetchRow($check_sql))
+{
+ if ($row['resolution_reason'] == 6) {
+ preg_match("/\b(?:FS#|bug )(\d+)\b/", $row['closure_comment'], $dupe_of);
+ if (count($dupe_of)) {
+ $existing = $db->query('SELECT * FROM {related} WHERE this_task = ? AND related_task = ? AND is_duplicate = 1',
+ array($row['task_id'], $dupe_of[1]));
+
+ if ($db->countRows($existing) == 0) {
+ $db->query('INSERT INTO {related} (this_task, related_task, is_duplicate) VALUES(?,?,1)',
+ array($row['task_id'], $dupe_of[1]));
+ echo $row['task_id'] . ' is a duplicate of ' . $dupe_of[1] . '.<br />';
+ }
+ }
+ }
+}
+
+$check_sql = $db->query('SELECT this_task, related_task FROM {related} WHERE is_duplicate = 0');
+$deleted = array();
+
+while ($row = $db->fetchRow($check_sql))
+{
+ $existing = $db->query('SELECT related_id FROM {related} WHERE this_task = ? AND related_task = ? AND is_duplicate = 0',
+ array($row['related_task'], $row['this_task']));
+
+ if ($db->countRows($existing) == 1 && !isset($deleted[$row['related_task'].'-'.$row['this_task']])) {
+ $deleted[$row['this_task'].'-'.$row['related_task']] = true;
+ $db->query('DELETE FROM {related} WHERE related_id = ?', array($db->fetchOne($existing)));
+ }
+}
+
+?>
diff --git a/setup/upgrade/0.9.9/add_searches.php b/setup/upgrade/0.9.9/add_searches.php
new file mode 100644
index 0000000..6e5031c
--- /dev/null
+++ b/setup/upgrade/0.9.9/add_searches.php
@@ -0,0 +1,22 @@
+<?php
+ /**********************************************************\
+ | This script addes some default saved searches for every |
+ | user. |
+ \***********************************************************/
+
+$check_sql = $db->query('SELECT user_id FROM {users}');
+
+while ($row = $db->fetchRow($check_sql))
+{
+ $db->query('DELETE FROM {searches} WHERE (name = ? OR name = ? OR name = ?) AND user_id = ?', array('Tasks I watch', 'Tasks assigned to me', 'Tasks I opened', $row['user_id']));
+ $db->query('INSERT INTO {searches} (user_id, name, search_string, time) VALUES (?, \'Tasks I watch\', \'a:16:{s:6:"string";N;s:4:"type";a:1:{i:0;s:0:"";}s:3:"sev";a:1:{i:0;s:0:"";}s:3:"due";a:1:{i:0;s:0:"";}s:3:"dev";N;s:3:"cat";a:1:{i:0;s:0:"";}s:6:"status";a:1:{i:0;s:4:"open";}s:5:"order";N;s:4:"sort";N;s:7:"percent";a:1:{i:0;s:0:"";}s:6:"opened";N;s:18:"search_in_comments";N;s:14:"search_for_all";N;s:8:"reported";a:1:{i:0;s:0:"";}s:12:"only_primary";N;s:12:"only_watched";s:1:"1";}\', ' . time() . ')',
+ array($row['user_id']));
+ $db->query('INSERT INTO {searches} (user_id, name, search_string, time) VALUES (?, \'Tasks assigned to me\', \'a:16:{s:6:"string";N;s:4:"type";a:1:{i:0;s:0:"";}s:3:"sev";a:1:{i:0;s:0:"";}s:3:"due";a:1:{i:0;s:0:"";}s:3:"dev";s:' . strlen($row['user_id']) . ':"' . $row['user_id'] .'";s:3:"cat";a:1:{i:0;s:0:"";}s:6:"status";a:1:{i:0;s:4:"open";}s:5:"order";N;s:4:"sort";N;s:7:"percent";a:1:{i:0;s:0:"";}s:6:"opened";N;s:18:"search_in_comments";N;s:14:"search_for_all";N;s:8:"reported";a:1:{i:0;s:0:"";}s:12:"only_primary";N;s:12:"only_watched";N;}\', ' . time() . ')',
+ array($row['user_id']));
+ $db->query('INSERT INTO {searches} (user_id, name, search_string, time) VALUES (?, \'Tasks I opened\', \'a:16:{s:6:"string";N;s:4:"type";a:1:{i:0;s:0:"";}s:3:"sev";a:1:{i:0;s:0:"";}s:3:"due";a:1:{i:0;s:0:"";}s:3:"dev";N;s:3:"cat";a:1:{i:0;s:0:"";}s:6:"status";a:1:{i:0;s:4:"open";}s:5:"order";N;s:4:"sort";N;s:7:"percent";a:1:{i:0;s:0:"";}s:6:"opened";s:' . strlen($row['user_id']) . ':"' . $row['user_id'] .'";s:18:"search_in_comments";N;s:14:"search_for_all";N;s:8:"reported";a:1:{i:0;s:0:"";}s:12:"only_primary";N;s:12:"only_watched";N;}\', ' . time() . ')',
+ array($row['user_id']));
+}
+
+
+?>
+
diff --git a/setup/upgrade/0.9.9/clean_unique.php b/setup/upgrade/0.9.9/clean_unique.php
new file mode 100644
index 0000000..652630b
--- /dev/null
+++ b/setup/upgrade/0.9.9/clean_unique.php
@@ -0,0 +1,67 @@
+<?php
+ /**********************************************************\
+ | This script removes duplicate db entries |
+ \**********************************************************/
+
+// Users
+
+$users = $db->query('SELECT * FROM {users} ORDER BY user_id ASC');
+
+while ($row = $db->fetchRow($users))
+{
+ if (!isset($deleted[$row['user_name']])) {
+ $deleted[$row['user_name']] = $row['user_id'];
+ }
+
+ $db->query('DELETE FROM {users} WHERE user_name = ? AND user_id != ?',
+ array($row['user_name'], $deleted[$row['user_name']]));
+}
+
+
+$users = $db->query('SELECT * FROM {registrations} ORDER BY reg_id ASC');
+
+while ($row = $db->fetchRow($users))
+{
+ if (!isset($deleted[$row['user_name']])) {
+ $deleted[$row['user_name']] = $row['reg_id'];
+ }
+
+ $db->query('DELETE FROM {registrations} WHERE user_name = ? AND reg_id != ?',
+ array($row['user_name'], $deleted[$row['user_name']]));
+}
+
+// Users in groups
+
+$sql = $db->query('SELECT * FROM {users_in_groups} ORDER BY record_id');
+while ($row = $db->fetchRow($sql))
+{
+ $db->query('DELETE FROM {users_in_groups} WHERE user_id = ? AND group_id = ? AND record_id <> ?',
+ array($row['user_id'], $row['group_id'], $row['record_id']));
+}
+
+// Group names
+
+$sql = $db->query('SELECT * FROM {groups} ORDER BY group_id ASC');
+while ($row = $db->fetchRow($sql))
+{
+ $col = 'belongs_to_project';
+ if (!isset($row[$col])) {
+ $col = 'project_id';
+ }
+
+ $db->query('DELETE FROM {groups} WHERE group_name = ? AND '.$col.' = ? AND group_id <> ?',
+ array($row['group_name'], $row[$col], $row['group_id']));
+}
+
+// Out of range value adjusted for column..
+$sql = $db->query('SELECT * FROM {tasks}');
+while ($row = $db->fetchRow($sql))
+{
+ $db->query('UPDATE {tasks} SET date_closed = ?, last_edited_time = ? WHERE task_id = ?',
+ array(intval($row['date_closed']), intval($row['last_edited_time']), $row['task_id']));
+ if (isset($row['due_date'])) {
+ $db->query('UPDATE {tasks} SET due_date = ? WHERE task_id = ?',
+ array(intval($row['due_date']), $row['task_id']));
+ }
+}
+?>
diff --git a/setup/upgrade/0.9.9/convert_categories.php b/setup/upgrade/0.9.9/convert_categories.php
new file mode 100644
index 0000000..99789ad
--- /dev/null
+++ b/setup/upgrade/0.9.9/convert_categories.php
@@ -0,0 +1,43 @@
+<?php
+ /**********************************************************\
+ | This script converts the categories table to the new |
+ | format. |
+ \***********************************************************/
+
+function rebuild_tree($parent, $left, $pr) {
+ global $db;
+ // the right value of this node is the left value + 1
+ $right = $left+1;
+
+ // get all children of this node
+ $result = $db->query('SELECT category_id FROM {list_category} WHERE parent_id = ? AND project_id = ?', array($parent, $pr));
+
+ while ($row = $db->fetchRow($result)) {
+ // recursive execution of this function for each
+ // child of this node
+ // $right is the current right value, which is
+ // incremented by the rebuild_tree function
+ $right = rebuild_tree($row['category_id'], $right, $pr);
+ }
+
+ // we've got the left value, and now that we've processed
+ // the children of this node we also know the right value
+ $db->query('UPDATE {list_category} SET lft= ?, rgt= ? WHERE category_id = ?', array($left, $right, $parent));
+ $sql = $db->query('SELECT * FROM {list_category} WHERE category_id = ? OR project_id=? AND parent_id=-1', array($parent, $pr));
+ if (!$db->countRows($sql)) {
+ $db->query('INSERT INTO {list_category} (project_id, lft, rgt, category_name, parent_id) VALUES(?,?,?,?,-1)',
+ array($pr,$left,$right,'root'));
+ }
+ // return the right value of this node + 1
+ return $right+1;
+}
+
+$projects = $db->query('SELECT project_id FROM {projects}');
+
+// Global project
+rebuild_tree(0, 1, 0);
+while ($pr = $db->fetchRow($projects)) {
+ rebuild_tree(0, 1, $pr['project_id']);
+}
+
+?>
diff --git a/setup/upgrade/0.9.9/convert_private.php b/setup/upgrade/0.9.9/convert_private.php
new file mode 100644
index 0000000..b871d39
--- /dev/null
+++ b/setup/upgrade/0.9.9/convert_private.php
@@ -0,0 +1,26 @@
+<?php
+ /**********************************************************\
+ | This script converts the private/public history entries |
+ \***********************************************************/
+
+
+$check_sql = $db->query('SELECT * FROM {history} WHERE event_type = 26 OR event_type = 27');
+
+while ($row = $db->fetchRow($check_sql))
+{
+ $db->query('DELETE FROM {history} WHERE history_id = ?', array($row['history_id']));
+ if ($row['event_type'] == 26) {
+ $row['old_value'] = 0;
+ $row['new_value'] = 1;
+ }
+ if ($row['event_type'] == 27) {
+ $row['old_value'] = 1;
+ $row['new_value'] = 0;
+ }
+ $db->query("INSERT INTO {history} (task_id, user_id, event_date, event_type, field_changed, old_value, new_value)
+ VALUES(?, ?, ?, 0, 'mark_private', ?, ?)",
+ array($row['task_id'], $row['user_id'], $row['event_date'], $row['old_value'], $row['new_value']));
+}
+
+
+?>
diff --git a/setup/upgrade/0.9.9/flyspray-begin.xml b/setup/upgrade/0.9.9/flyspray-begin.xml
new file mode 100644
index 0000000..aac979a
--- /dev/null
+++ b/setup/upgrade/0.9.9/flyspray-begin.xml
@@ -0,0 +1,748 @@
+<?xml version="1.0"?>
+<schema version="0.3">
+ <table name="admin_requests">
+ <field name="request_id" type="I" size="5">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="project_id" type="I" size="5">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="task_id" type="I" size="5">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="submitted_by" type="I" size="5">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="request_type" type="I" size="2">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="reason_given" type="X">
+ <NOTNULL/>
+ </field>
+ <field name="time_submitted" type="C" size="12">
+ <NOTNULL/>
+ </field>
+ <field name="resolved_by" type="I" size="5">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="time_resolved" type="C" size="12">
+ <NOTNULL/>
+ </field>
+ <field name="deny_reason" type="C" size="255">
+ <NOTNULL/>
+ </field>
+ </table>
+ <table name="assigned">
+ <field name="assigned_id" type="I" size="10">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="task_id" type="I" size="10">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="user_or_group" type="C" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="user_id" type="I" size="5">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ </table>
+ <table name="attachments">
+ <field name="attachment_id" type="I" size="5">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="task_id" type="I" size="10">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="comment_id" type="I" size="10">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="orig_name" type="C" size="255">
+ <NOTNULL/>
+ </field>
+ <field name="file_name" type="C" size="30">
+ <NOTNULL/>
+ </field>
+ <field name="file_type" type="C" size="50">
+ <NOTNULL/>
+ </field>
+ <field name="file_size" type="I" size="20">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="added_by" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="date_added" type="C" size="12">
+ <NOTNULL/>
+ </field>
+ </table>
+ <table name="comments">
+ <field name="comment_id" type="I" size="10">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="task_id" type="I" size="10">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="date_added" type="C" size="12">
+ <NOTNULL/>
+ </field>
+ <field name="user_id" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="comment_text" type="X">
+ <NOTNULL/>
+ </field>
+ </table>
+ <table name="dependencies">
+ <field name="depend_id" type="I" size="10">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="task_id" type="I" size="10">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="dep_task_id" type="I" size="10">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ </table>
+ <table name="groups">
+ <field name="group_id" type="I" size="3">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="group_name" type="C" size="20">
+ <NOTNULL/>
+ </field>
+ <field name="group_desc" type="C" size="150">
+ <NOTNULL/>
+ </field>
+ <field name="belongs_to_project" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="is_admin" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="manage_project" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="view_tasks" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="open_new_tasks" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="modify_own_tasks" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="modify_all_tasks" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="view_comments" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="add_comments" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="edit_comments" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="delete_comments" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="view_attachments" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="create_attachments" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="delete_attachments" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="view_history" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="close_own_tasks" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="close_other_tasks" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="assign_to_self" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="assign_others_to_self" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="view_reports" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="group_open" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ </table>
+ <table name="history">
+ <field name="history_id" type="I" size="10">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="task_id" type="I" size="10">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="user_id" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="event_date" type="X">
+ <NOTNULL/>
+ </field>
+ <field name="event_type" type="I" size="2">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="field_changed" type="X">
+ <NOTNULL/>
+ </field>
+ <field name="old_value" type="X">
+ <NOTNULL/>
+ </field>
+ <field name="new_value" type="X">
+ <NOTNULL/>
+ </field>
+ </table>
+ <table name="list_category">
+ <field name="category_id" type="I" size="3">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="project_id" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="category_name" type="C" size="40">
+ <NOTNULL/>
+ </field>
+ <field name="list_position" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="show_in_list" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="category_owner" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="supertask_id" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="lft" type="I" size="10">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ <UNSIGNED/>
+ </field>
+ <field name="rgt" type="I" size="10">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ <UNSIGNED/>
+ </field>
+ </table>
+ <table name="list_os">
+ <field name="os_id" type="I" size="3">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="project_id" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="os_name" type="C" size="40">
+ <NOTNULL/>
+ </field>
+ <field name="list_position" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="show_in_list" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ </table>
+ <table name="list_resolution">
+ <field name="resolution_id" type="I" size="3">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="resolution_name" type="C" size="40">
+ <NOTNULL/>
+ </field>
+ <field name="list_position" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="show_in_list" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="project_id" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ </table>
+ <table name="list_tasktype">
+ <field name="tasktype_id" type="I" size="3">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="tasktype_name" type="C" size="40">
+ <NOTNULL/>
+ </field>
+ <field name="list_position" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="show_in_list" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="project_id" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ </table>
+ <table name="list_version">
+ <field name="version_id" type="I" size="3">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="project_id" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="version_name" type="C" size="40">
+ <NOTNULL/>
+ </field>
+ <field name="list_position" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="show_in_list" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="version_tense" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ </table>
+ <table name="notification_messages">
+ <field name="message_id" type="I" size="10">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="message_subject" type="C" size="50">
+ <NOTNULL/>
+ </field>
+ <field name="message_body" type="X">
+ <NOTNULL/>
+ </field>
+ <field name="time_created" type="C" size="20"/>
+ </table>
+ <table name="notification_recipients">
+ <field name="recipient_id" type="I" size="10">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="message_id" type="I" size="10">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="notify_method" type="C" size="1">
+ <NOTNULL/>
+ </field>
+ <field name="notify_address" type="C" size="100">
+ <NOTNULL/>
+ </field>
+ </table>
+ <table name="notifications">
+ <field name="notify_id" type="I" size="10">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="task_id" type="I" size="10">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="user_id" type="I" size="5">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ </table>
+ <table name="prefs">
+ <field name="pref_id" type="I" size="1">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="pref_name" type="C" size="30">
+ <NOTNULL/>
+ </field>
+ <field name="pref_value" type="C" size="250">
+ <NOTNULL/>
+ </field>
+ </table>
+ <table name="projects">
+ <field name="project_id" type="I" size="3">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="project_title" type="C" size="100">
+ <NOTNULL/>
+ </field>
+ <field name="theme_style" type="C" size="20">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="show_logo" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="inline_images" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="default_cat_owner" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="intro_message" type="X">
+ <NOTNULL/>
+ </field>
+ <field name="project_is_active" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="visible_columns" type="C" size="255">
+ <NOTNULL/>
+ </field>
+ <field name="others_view" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="anon_open" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="notify_email" type="X">
+ <NOTNULL/>
+ </field>
+ <field name="notify_email_when" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="notify_jabber" type="X">
+ <NOTNULL/>
+ </field>
+ <field name="notify_jabber_when" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ </table>
+ <table name="registrations">
+ <field name="reg_id" type="I" size="10">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="reg_time" type="C" size="12">
+ <NOTNULL/>
+ </field>
+ <field name="confirm_code" type="C" size="20">
+ <NOTNULL/>
+ </field>
+ <field name="user_name" type="C" size="20">
+ <NOTNULL/>
+ </field>
+ <field name="real_name" type="C" size="100">
+ <NOTNULL/>
+ </field>
+ <field name="email_address" type="C" size="100">
+ <NOTNULL/>
+ </field>
+ <field name="jabber_id" type="C" size="100">
+ <NOTNULL/>
+ </field>
+ <field name="notify_type" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="magic_url" type="C" size="40">
+ <NOTNULL/>
+ </field>
+ </table>
+ <table name="related">
+ <field name="related_id" type="I" size="10">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="this_task" type="I" size="10">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="related_task" type="I" size="10">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="is_duplicate" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ </table>
+ <table name="reminders">
+ <field name="reminder_id" type="I" size="10">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="task_id" type="I" size="10">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="to_user_id" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="from_user_id" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="start_time" type="C" size="12">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="how_often" type="I" size="12">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="last_sent" type="C" size="12">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="reminder_message" type="X">
+ <NOTNULL/>
+ </field>
+ </table>
+ <table name="searches">
+ <field name="id" type="I" size="11">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="user_id" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="name" type="C" size="50">
+ <NOTNULL/>
+ </field>
+ <field name="search_string" type="X">
+ <NOTNULL/>
+ </field>
+ <field name="time" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ </table>
+ <table name="tasks">
+ <field name="task_id" type="I" size="10">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="attached_to_project" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="task_type" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="date_opened" type="C" size="12">
+ <NOTNULL/>
+ </field>
+ <field name="opened_by" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="is_closed" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="date_closed" type="C" size="12">
+ <NOTNULL/>
+ </field>
+ <field name="closed_by" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="closure_comment" type="X">
+ <NOTNULL/>
+ </field>
+ <field name="item_summary" type="C" size="100">
+ <NOTNULL/>
+ </field>
+ <field name="detailed_desc" type="X">
+ <NOTNULL/>
+ </field>
+ <field name="item_status" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="assigned_to" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="resolution_reason" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="1"/>
+ </field>
+ <field name="product_category" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="product_version" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="closedby_version" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="operating_system" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="task_severity" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="task_priority" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="last_edited_by" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="last_edited_time" type="C" size="12">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="percent_complete" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="mark_private" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="due_date" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ </table>
+ <table name="users">
+ <field name="user_id" type="I" size="3">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="user_name" type="C" size="20">
+ <NOTNULL/>
+ </field>
+ <field name="user_pass" type="C" size="40"/>
+ <field name="real_name" type="C" size="100">
+ <NOTNULL/>
+ </field>
+ <field name="jabber_id" type="C" size="100">
+ <NOTNULL/>
+ </field>
+ <field name="email_address" type="C" size="100">
+ <NOTNULL/>
+ </field>
+ <field name="notify_type" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="account_enabled" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="dateformat" type="C" size="30">
+ <NOTNULL/>
+ </field>
+ <field name="dateformat_extended" type="C" size="30">
+ <NOTNULL/>
+ </field>
+ <field name="magic_url" type="C" size="40">
+ <NOTNULL/>
+ </field>
+ <field name="last_search" type="X">
+ <NOTNULL/>
+ </field>
+ <field name="tasks_perpage" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ </table>
+ <table name="users_in_groups">
+ <field name="record_id" type="I" size="5">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="user_id" type="I" size="5">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="group_id" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ </table>
+</schema>
diff --git a/setup/upgrade/0.9.9/flyspray-final.xml b/setup/upgrade/0.9.9/flyspray-final.xml
new file mode 100644
index 0000000..5db6a96
--- /dev/null
+++ b/setup/upgrade/0.9.9/flyspray-final.xml
@@ -0,0 +1,976 @@
+<?xml version="1.0"?>
+<schema version="0.3">
+ <table name="admin_requests">
+ <field name="request_id" type="I" size="5">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="project_id" type="I" size="5">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="task_id" type="I" size="5">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="submitted_by" type="I" size="5">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="request_type" type="I" size="2">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="reason_given" type="X">
+ <NOTNULL/>
+ </field>
+ <field name="time_submitted" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="resolved_by" type="I" size="5">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="time_resolved" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="deny_reason" type="C" size="255">
+ <NOTNULL/>
+ </field>
+ </table>
+ <table name="assigned">
+ <field name="assigned_id" type="I" size="10">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="task_id" type="I" size="10">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="user_id" type="I" size="5">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="task_user">
+ <UNIQUE/>
+ <col>task_id</col>
+ <col>user_id</col>
+ </index>
+ <index name="task_id_assigned">
+ <col>task_id</col>
+ <col>user_id</col>
+ </index>
+ </table>
+ <table name="attachments">
+ <field name="attachment_id" type="I" size="5">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="task_id" type="I" size="10">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="comment_id" type="I" size="10">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="orig_name" type="C" size="255">
+ <NOTNULL/>
+ </field>
+ <field name="file_name" type="C" size="30">
+ <NOTNULL/>
+ </field>
+ <field name="file_type" type="C" size="50">
+ <NOTNULL/>
+ </field>
+ <field name="file_size" type="I" size="20">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="added_by" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="date_added" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="task_id_attachments">
+ <col>task_id</col>
+ <col>comment_id</col>
+ </index>
+ </table>
+ <table name="cache">
+ <field name="id" type="I" size="6">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="type" type="C" size="4">
+ <NOTNULL/>
+ </field>
+ <field name="content" type="X">
+ <NOTNULL/>
+ </field>
+ <field name="topic" type="C" size="30">
+ <NOTNULL/>
+ </field>
+ <field name="last_updated" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="project_id" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="max_items" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="cache_type">
+ <UNIQUE/>
+ <col>type</col>
+ <col>topic</col>
+ <col>project_id</col>
+ <col>max_items</col>
+ </index>
+ </table>
+ <table name="comments">
+ <field name="comment_id" type="I" size="10">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="task_id" type="I" size="10">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="date_added" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="user_id" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="comment_text" type="X">
+ <NOTNULL/>
+ </field>
+ <field name="last_edited_time" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="task_id_comments">
+ <col>task_id</col>
+ </index>
+ </table>
+ <table name="dependencies">
+ <field name="depend_id" type="I" size="10">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="task_id" type="I" size="10">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="dep_task_id" type="I" size="10">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="task_id_deps">
+ <UNIQUE/>
+ <col>task_id</col>
+ <col>dep_task_id</col>
+ </index>
+ </table>
+ <table name="groups">
+ <field name="group_id" type="I" size="3">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="group_name" type="C" size="20">
+ <NOTNULL/>
+ </field>
+ <field name="group_desc" type="C" size="150">
+ <NOTNULL/>
+ </field>
+ <field name="project_id" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="is_admin" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="manage_project" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="view_tasks" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="open_new_tasks" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="modify_own_tasks" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="modify_all_tasks" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="view_comments" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="add_comments" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="edit_comments" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="edit_own_comments" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="delete_comments" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="create_attachments" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="delete_attachments" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="view_history" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="close_own_tasks" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="close_other_tasks" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="assign_to_self" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="assign_others_to_self" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="add_to_assignees" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="view_reports" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="add_votes" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="edit_assignments" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="group_open" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="group_name">
+ <UNIQUE/>
+ <col>group_name</col>
+ <col>project_id</col>
+ </index>
+ <index name="belongs_to_project">
+ <col>project_id</col>
+ </index>
+ </table>
+ <table name="history">
+ <field name="history_id" type="I" size="10">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="task_id" type="I" size="10">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="user_id" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="event_date" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="event_type" type="I" size="2">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="field_changed" type="C" size="50">
+ <NOTNULL/>
+ </field>
+ <field name="old_value" type="X" />
+ <field name="new_value" type="X" />
+ <index name="idx_task_id">
+ <col>task_id</col>
+ </index>
+ </table>
+ <table name="list_category">
+ <field name="category_id" type="I" size="3">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="project_id" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="category_name" type="C" size="40">
+ <NOTNULL/>
+ </field>
+ <field name="show_in_list" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="category_owner" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="lft" type="I" size="10">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ <UNSIGNED/>
+ </field>
+ <field name="rgt" type="I" size="10">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ <UNSIGNED/>
+ </field>
+ <index name="project_id_cat">
+ <col>project_id</col>
+ </index>
+ </table>
+ <table name="list_os">
+ <field name="os_id" type="I" size="3">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="project_id" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="os_name" type="C" size="40">
+ <NOTNULL/>
+ </field>
+ <field name="list_position" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="show_in_list" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="project_id_os">
+ <col>project_id</col>
+ </index>
+ </table>
+ <table name="list_resolution">
+ <field name="resolution_id" type="I" size="3">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="resolution_name" type="C" size="40">
+ <NOTNULL/>
+ </field>
+ <field name="list_position" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="show_in_list" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="project_id" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="project_id_res">
+ <col>project_id</col>
+ </index>
+ </table>
+ <table name="list_status">
+ <field name="status_id" type="I" size="3">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="status_name" type="C" size="40">
+ <NOTNULL/>
+ </field>
+ <field name="list_position" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="show_in_list" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="project_id" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="project_id_status">
+ <col>project_id</col>
+ </index>
+ </table>
+ <table name="list_tasktype">
+ <field name="tasktype_id" type="I" size="3">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="tasktype_name" type="C" size="40">
+ <NOTNULL/>
+ </field>
+ <field name="list_position" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="show_in_list" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="project_id" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="project_id_tt">
+ <col>project_id</col>
+ </index>
+ </table>
+ <table name="list_version">
+ <field name="version_id" type="I" size="3">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="project_id" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="version_name" type="C" size="40">
+ <NOTNULL/>
+ </field>
+ <field name="list_position" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="show_in_list" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="version_tense" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="project_id_version">
+ <col>project_id</col>
+ <col>version_tense</col>
+ </index>
+ </table>
+ <table name="notification_messages">
+ <field name="message_id" type="I" size="10">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="message_subject" type="X">
+ <NOTNULL/>
+ </field>
+ <field name="message_body" type="X">
+ <NOTNULL/>
+ </field>
+ <field name="time_created" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ </table>
+ <table name="notification_recipients">
+ <field name="recipient_id" type="I" size="10">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="message_id" type="I" size="10">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="notify_method" type="C" size="1">
+ <NOTNULL/>
+ </field>
+ <field name="notify_address" type="C" size="100">
+ <NOTNULL/>
+ </field>
+ </table>
+ <table name="notifications">
+ <field name="notify_id" type="I" size="10">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="task_id" type="I" size="10">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="user_id" type="I" size="5">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ </table>
+ <table name="prefs">
+ <field name="pref_id" type="I" size="1">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="pref_name" type="C" size="30">
+ <NOTNULL/>
+ </field>
+ <field name="pref_value" type="C" size="250">
+ <DEFAULT value="0"/>
+ <NOTNULL/>
+ </field>
+ </table>
+ <table name="projects">
+ <field name="project_id" type="I" size="3">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="project_title" type="C" size="100">
+ <NOTNULL/>
+ </field>
+ <field name="theme_style" type="C" size="20">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="default_cat_owner" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="intro_message" type="X">
+ <NOTNULL/>
+ <DEFAULT value=""/>
+ </field>
+ <field name="project_is_active" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="visible_columns" type="C" size="255">
+ <NOTNULL/>
+ </field>
+ <field name="others_view" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="anon_open" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="notify_email" type="X">
+ <NOTNULL/>
+ <DEFAULT value=""/>
+ </field>
+ <field name="notify_jabber" type="X">
+ <NOTNULL/>
+ <DEFAULT value=""/>
+ </field>
+ <field name="notify_reply" type="X">
+ <NOTNULL/>
+ <DEFAULT value=""/>
+ </field>
+ <field name="notify_types" type="C" size="100">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="feed_img_url" type="X">
+ <NOTNULL/>
+ <DEFAULT value=""/>
+ </field>
+ <field name="feed_description" type="X">
+ <NOTNULL/>
+ <DEFAULT value=""/>
+ </field>
+ <field name="notify_subject" type="C" size="100">
+ <NOTNULL/>
+ <DEFAULT value=""/>
+ </field>
+ <field name="lang_code" type="C" size="10">
+ <NOTNULL/>
+ <DEFAULT value="en"/>
+ </field>
+ <field name="comment_closed" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="auto_assign" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="last_updated" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="default_task" type="X">
+ <NOTNULL/>
+ </field>
+ <field name="default_entry" type="C" size="8">
+ <NOTNULL/>
+ <DEFAULT value="index"/>
+ </field>
+ </table>
+ <table name="registrations">
+ <field name="reg_id" type="I" size="10">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="reg_time" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="confirm_code" type="C" size="20">
+ <NOTNULL/>
+ </field>
+ <field name="user_name" type="C" size="32">
+ <NOTNULL/>
+ </field>
+ <field name="real_name" type="C" size="100">
+ <NOTNULL/>
+ </field>
+ <field name="email_address" type="C" size="100">
+ <NOTNULL/>
+ </field>
+ <field name="jabber_id" type="C" size="100">
+ <NOTNULL/>
+ </field>
+ <field name="notify_type" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="magic_url" type="C" size="40">
+ <NOTNULL/>
+ </field>
+ <field name="time_zone" type="I" size="6">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ </table>
+ <table name="related">
+ <field name="related_id" type="I" size="10">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="this_task" type="I" size="10">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="related_task" type="I" size="10">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="is_duplicate" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="this_task">
+ <UNIQUE/>
+ <col>this_task</col>
+ <col>related_task</col>
+ <col>is_duplicate</col>
+ </index>
+ </table>
+ <table name="reminders">
+ <field name="reminder_id" type="I" size="10">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="task_id" type="I" size="10">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="to_user_id" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="from_user_id" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="start_time" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="how_often" type="I" size="12">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="last_sent" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="reminder_message" type="X">
+ <NOTNULL/>
+ </field>
+ </table>
+ <table name="searches">
+ <field name="id" type="I" size="11">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="user_id" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="name" type="C" size="50">
+ <NOTNULL/>
+ </field>
+ <field name="search_string" type="X">
+ <NOTNULL/>
+ </field>
+ <field name="time" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ </table>
+ <table name="tasks">
+ <field name="task_id" type="I" size="10">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="project_id" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="task_type" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="date_opened" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="opened_by" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="is_closed" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="date_closed" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="closed_by" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="closure_comment" type="X">
+ <NOTNULL/>
+ </field>
+ <field name="item_summary" type="C" size="100">
+ <NOTNULL/>
+ </field>
+ <field name="detailed_desc" type="X">
+ <NOTNULL/>
+ </field>
+ <field name="item_status" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="resolution_reason" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="1"/>
+ </field>
+ <field name="product_category" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="product_version" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="closedby_version" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="operating_system" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="task_severity" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="task_priority" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="last_edited_by" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="last_edited_time" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="percent_complete" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="mark_private" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="due_date" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="anon_email" type="C" size="100">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="task_token" type="C" size="32">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="attached_to_project">
+ <col>project_id</col>
+ </index>
+ <index name="task_severity">
+ <col>task_severity</col>
+ </index>
+ <index name="task_type">
+ <col>task_type</col>
+ </index>
+ <index name="product_category">
+ <col>product_category</col>
+ </index>
+ <index name="item_status">
+ <col>item_status</col>
+ </index>
+ <index name="is_closed">
+ <col>is_closed</col>
+ </index>
+ <index name="closedby_version">
+ <col>closedby_version</col>
+ </index>
+ <index name="due_date">
+ <col>due_date</col>
+ </index>
+ </table>
+ <table name="users">
+ <field name="user_id" type="I" size="3">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="user_name" type="C" size="32">
+ <NOTNULL/>
+ </field>
+ <field name="user_pass" type="C" size="40"/>
+ <field name="real_name" type="C" size="100">
+ <NOTNULL/>
+ </field>
+ <field name="jabber_id" type="C" size="100">
+ <NOTNULL/>
+ </field>
+ <field name="email_address" type="C" size="100">
+ <NOTNULL/>
+ </field>
+ <field name="notify_type" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="notify_own" type="I" size="6">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="account_enabled" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="dateformat" type="C" size="30">
+ <NOTNULL/>
+ <DEFAULT value=""/>
+ </field>
+ <field name="dateformat_extended" type="C" size="30">
+ <NOTNULL/>
+ <DEFAULT value=""/>
+ </field>
+ <field name="magic_url" type="C" size="40">
+ <NOTNULL/>
+ <DEFAULT value=""/>
+ </field>
+ <field name="tasks_perpage" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="register_date" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="time_zone" type="I" size="6">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="user_name">
+ <UNIQUE/>
+ <col>user_name</col>
+ </index>
+ </table>
+ <table name="users_in_groups">
+ <field name="record_id" type="I" size="5">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="user_id" type="I" size="5">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="group_id" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="group_id_uig">
+ <UNIQUE/>
+ <col>group_id</col>
+ <col>user_id</col>
+ </index>
+ <index name="user_id_uig">
+ <col>user_id</col>
+ </index>
+ </table>
+ <table name="votes">
+ <field name="vote_id" type="I" size="11">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="user_id" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="task_id" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="date_time" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ </table>
+</schema>
diff --git a/setup/upgrade/0.9.9/flyspray-install.xml b/setup/upgrade/0.9.9/flyspray-install.xml
new file mode 100644
index 0000000..7496241
--- /dev/null
+++ b/setup/upgrade/0.9.9/flyspray-install.xml
@@ -0,0 +1,1044 @@
+<?xml version="1.0"?>
+<schema version="0.3">
+ <table name="admin_requests">
+ <field name="request_id" type="I" size="5">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="project_id" type="I" size="5">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="task_id" type="I" size="5">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="submitted_by" type="I" size="5">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="request_type" type="I" size="2">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="reason_given" type="X">
+ <NOTNULL/>
+ </field>
+ <field name="time_submitted" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="resolved_by" type="I" size="5">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="time_resolved" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="deny_reason" type="C" size="255">
+ <NOTNULL/>
+ </field>
+ </table>
+ <table name="assigned">
+ <field name="assigned_id" type="I" size="10">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="task_id" type="I" size="10">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="user_id" type="I" size="5">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="task_user">
+ <UNIQUE/>
+ <col>task_id</col>
+ <col>user_id</col>
+ </index>
+ <index name="task_id_assigned">
+ <col>task_id</col>
+ <col>user_id</col>
+ </index>
+ </table>
+ <table name="attachments">
+ <field name="attachment_id" type="I" size="5">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="task_id" type="I" size="10">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="comment_id" type="I" size="10">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="orig_name" type="C" size="100">
+ <NOTNULL/>
+ </field>
+ <field name="file_name" type="C" size="30">
+ <NOTNULL/>
+ </field>
+ <field name="file_desc" type="C" size="100">
+ <NOTNULL/>
+ </field>
+ <field name="file_type" type="C" size="50">
+ <NOTNULL/>
+ </field>
+ <field name="file_size" type="I" size="20">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="added_by" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="date_added" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="task_id_attachments">
+ <col>task_id</col>
+ <col>comment_id</col>
+ </index>
+ </table>
+ <table name="cache">
+ <field name="id" type="I" size="6">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="type" type="C" size="4">
+ <NOTNULL/>
+ </field>
+ <field name="content" type="X">
+ <NOTNULL/>
+ </field>
+ <field name="topic" type="C" size="30">
+ <NOTNULL/>
+ </field>
+ <field name="last_updated" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="project_id" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="max_items" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="cache_type">
+ <UNIQUE/>
+ <col>type</col>
+ <col>topic</col>
+ <col>project_id</col>
+ <col>max_items</col>
+ </index>
+ </table>
+ <table name="comments">
+ <field name="comment_id" type="I" size="10">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="task_id" type="I" size="10">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="date_added" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="user_id" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="comment_text" type="X">
+ <NOTNULL/>
+ </field>
+ <field name="last_edited_time" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="task_id_comments">
+ <col>task_id</col>
+ </index>
+ </table>
+ <table name="dependencies">
+ <field name="depend_id" type="I" size="10">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="task_id" type="I" size="10">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="dep_task_id" type="I" size="10">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="task_id_deps">
+ <UNIQUE/>
+ <col>task_id</col>
+ <col>dep_task_id</col>
+ </index>
+ </table>
+ <table name="groups">
+ <field name="group_id" type="I" size="3">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="group_name" type="C" size="20">
+ <NOTNULL/>
+ </field>
+ <field name="group_desc" type="C" size="150">
+ <NOTNULL/>
+ </field>
+ <field name="project_id" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="is_admin" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="manage_project" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="view_tasks" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="open_new_tasks" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="modify_own_tasks" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="modify_all_tasks" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="view_comments" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="add_comments" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="edit_comments" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="edit_own_comments" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="delete_comments" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="create_attachments" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="delete_attachments" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="view_history" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="close_own_tasks" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="close_other_tasks" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="assign_to_self" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="assign_others_to_self" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="add_to_assignees" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="view_reports" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="add_votes" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="edit_assignments" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="group_open" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="group_name">
+ <UNIQUE/>
+ <col>group_name</col>
+ <col>project_id</col>
+ </index>
+ <index name="belongs_to_project">
+ <col>project_id</col>
+ </index>
+ </table>
+ <table name="history">
+ <field name="history_id" type="I" size="10">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="task_id" type="I" size="10">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="user_id" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="event_date" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="event_type" type="I" size="2">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="field_changed" type="C" size="50">
+ <NOTNULL/>
+ </field>
+ <field name="old_value" type="X" />
+ <field name="new_value" type="X" />
+ <index name="idx_task_id">
+ <col>task_id</col>
+ </index>
+ </table>
+ <table name="list_category">
+ <field name="category_id" type="I" size="3">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="project_id" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="category_name" type="C" size="30">
+ <NOTNULL/>
+ </field>
+ <field name="show_in_list" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="category_owner" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="lft" type="I" size="10">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ <UNSIGNED/>
+ </field>
+ <field name="rgt" type="I" size="10">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ <UNSIGNED/>
+ </field>
+ <index name="project_id_cat">
+ <col>project_id</col>
+ </index>
+ </table>
+ <table name="list_os">
+ <field name="os_id" type="I" size="3">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="project_id" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="os_name" type="C" size="20">
+ <NOTNULL/>
+ </field>
+ <field name="list_position" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="show_in_list" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="project_id_os">
+ <col>project_id</col>
+ </index>
+ </table>
+ <table name="list_resolution">
+ <field name="resolution_id" type="I" size="3">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="resolution_name" type="C" size="30">
+ <NOTNULL/>
+ </field>
+ <field name="list_position" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="show_in_list" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="project_id" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="project_id_res">
+ <col>project_id</col>
+ </index>
+ </table>
+ <table name="list_status">
+ <field name="status_id" type="I" size="3">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="status_name" type="C" size="20">
+ <NOTNULL/>
+ </field>
+ <field name="list_position" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="show_in_list" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="project_id" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="project_id_status">
+ <col>project_id</col>
+ </index>
+ </table>
+ <table name="list_tasktype">
+ <field name="tasktype_id" type="I" size="3">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="tasktype_name" type="C" size="20">
+ <NOTNULL/>
+ </field>
+ <field name="list_position" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="show_in_list" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="project_id" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="project_id_tt">
+ <col>project_id</col>
+ </index>
+ </table>
+ <table name="list_version">
+ <field name="version_id" type="I" size="3">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="project_id" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="version_name" type="C" size="20">
+ <NOTNULL/>
+ </field>
+ <field name="list_position" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="show_in_list" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="version_tense" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="project_id_version">
+ <col>project_id</col>
+ <col>version_tense</col>
+ </index>
+ </table>
+ <table name="notification_messages">
+ <field name="message_id" type="I" size="10">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="message_subject" type="X">
+ <NOTNULL/>
+ </field>
+ <field name="message_body" type="X">
+ <NOTNULL/>
+ </field>
+ <field name="time_created" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ </table>
+ <table name="notification_recipients">
+ <field name="recipient_id" type="I" size="10">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="message_id" type="I" size="10">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="notify_method" type="C" size="1">
+ <NOTNULL/>
+ </field>
+ <field name="notify_address" type="C" size="100">
+ <NOTNULL/>
+ </field>
+ </table>
+ <table name="notifications">
+ <field name="notify_id" type="I" size="10">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="task_id" type="I" size="10">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="user_id" type="I" size="5">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="task_id_notifs">
+ <UNIQUE/>
+ <col>task_id</col>
+ <col>user_id</col>
+ </index>
+ </table>
+ <table name="prefs">
+ <field name="pref_id" type="I" size="1">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="pref_name" type="C" size="20">
+ <NOTNULL/>
+ </field>
+ <field name="pref_value" type="C" size="250">
+ <DEFAULT value="0"/>
+ <NOTNULL/>
+ </field>
+ </table>
+ <table name="projects">
+ <field name="project_id" type="I" size="3">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="project_title" type="C" size="100">
+ <NOTNULL/>
+ </field>
+ <field name="theme_style" type="C" size="20">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="default_cat_owner" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="intro_message" type="X">
+ <NOTNULL/>
+ <DEFAULT value=""/>
+ </field>
+ <field name="project_is_active" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="visible_columns" type="C" size="255">
+ <NOTNULL/>
+ </field>
+ <field name="others_view" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="anon_open" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="notify_email" type="X">
+ <NOTNULL/>
+ <DEFAULT value=""/>
+ </field>
+ <field name="notify_jabber" type="X">
+ <NOTNULL/>
+ <DEFAULT value=""/>
+ </field>
+ <field name="notify_reply" type="X">
+ <NOTNULL/>
+ <DEFAULT value=""/>
+ </field>
+ <field name="notify_types" type="C" size="100">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="feed_img_url" type="X">
+ <NOTNULL/>
+ <DEFAULT value=""/>
+ </field>
+ <field name="feed_description" type="X">
+ <NOTNULL/>
+ <DEFAULT value=""/>
+ </field>
+ <field name="notify_subject" type="C" size="100">
+ <NOTNULL/>
+ <DEFAULT value=""/>
+ </field>
+ <field name="lang_code" type="C" size="10">
+ <NOTNULL/>
+ </field>
+ <field name="comment_closed" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="auto_assign" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="last_updated" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="default_task" type="X">
+ <NOTNULL/>
+ </field>
+ <field name="default_entry" type="C" size="8">
+ <NOTNULL/>
+ <DEFAULT value="index"/>
+ </field>
+ </table>
+ <table name="registrations">
+ <field name="reg_id" type="I" size="10">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="reg_time" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="confirm_code" type="C" size="20">
+ <NOTNULL/>
+ </field>
+ <field name="user_name" type="C" size="32">
+ <NOTNULL/>
+ </field>
+ <field name="real_name" type="C" size="100">
+ <NOTNULL/>
+ </field>
+ <field name="email_address" type="C" size="100">
+ <NOTNULL/>
+ </field>
+ <field name="jabber_id" type="C" size="100">
+ <NOTNULL/>
+ </field>
+ <field name="notify_type" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="magic_url" type="C" size="40">
+ <NOTNULL/>
+ </field>
+ <field name="time_zone" type="I" size="6">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ </table>
+ <table name="related">
+ <field name="related_id" type="I" size="10">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="this_task" type="I" size="10">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="related_task" type="I" size="10">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="is_duplicate" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="this_task">
+ <UNIQUE/>
+ <col>this_task</col>
+ <col>related_task</col>
+ <col>is_duplicate</col>
+ </index>
+ </table>
+ <table name="reminders">
+ <field name="reminder_id" type="I" size="10">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="task_id" type="I" size="10">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="to_user_id" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="from_user_id" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="start_time" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="how_often" type="I" size="12">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="last_sent" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="reminder_message" type="X">
+ <NOTNULL/>
+ </field>
+ </table>
+ <table name="searches">
+ <field name="id" type="I" size="11">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="user_id" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="name" type="C" size="50">
+ <NOTNULL/>
+ </field>
+ <field name="search_string" type="X">
+ <NOTNULL/>
+ </field>
+ <field name="time" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ </table>
+ <table name="tasks">
+ <field name="task_id" type="I" size="10">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="project_id" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="task_type" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="date_opened" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="opened_by" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="is_closed" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="date_closed" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="closed_by" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="closure_comment" type="X">
+ <NOTNULL/>
+ </field>
+ <field name="item_summary" type="C" size="100">
+ <NOTNULL/>
+ </field>
+ <field name="detailed_desc" type="X">
+ <NOTNULL/>
+ </field>
+ <field name="item_status" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="resolution_reason" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="1"/>
+ </field>
+ <field name="product_category" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="product_version" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="closedby_version" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="operating_system" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="task_severity" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="task_priority" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="last_edited_by" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="last_edited_time" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="percent_complete" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="mark_private" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="due_date" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="anon_email" type="C" size="100">
+ <NOTNULL/>
+ <DEFAULT value=""/>
+ </field>
+ <field name="task_token" type="C" size="32">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="attached_to_project">
+ <col>project_id</col>
+ </index>
+ <index name="task_severity">
+ <col>task_severity</col>
+ </index>
+ <index name="task_type">
+ <col>task_type</col>
+ </index>
+ <index name="product_category">
+ <col>product_category</col>
+ </index>
+ <index name="item_status">
+ <col>item_status</col>
+ </index>
+ <index name="is_closed">
+ <col>is_closed</col>
+ </index>
+ <index name="closedby_version">
+ <col>closedby_version</col>
+ </index>
+ <index name="due_date">
+ <col>due_date</col>
+ </index>
+ </table>
+ <table name="users">
+ <field name="user_id" type="I" size="3">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="user_name" type="C" size="32">
+ <NOTNULL/>
+ </field>
+ <field name="user_pass" type="C" size="40"/>
+ <field name="real_name" type="C" size="100">
+ <NOTNULL/>
+ </field>
+ <field name="jabber_id" type="C" size="100">
+ <NOTNULL/>
+ </field>
+ <field name="email_address" type="C" size="100">
+ <NOTNULL/>
+ </field>
+ <field name="notify_type" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="notify_own" type="I" size="6">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="account_enabled" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="dateformat" type="C" size="30">
+ <NOTNULL/>
+ <DEFAULT value=""/>
+ </field>
+ <field name="dateformat_extended" type="C" size="30">
+ <NOTNULL/>
+ <DEFAULT value=""/>
+ </field>
+ <field name="magic_url" type="C" size="40">
+ <NOTNULL/>
+ <DEFAULT value=""/>
+ </field>
+ <field name="tasks_perpage" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="register_date" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="time_zone" type="I" size="6">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="user_name">
+ <UNIQUE/>
+ <col>user_name</col>
+ </index>
+ </table>
+ <table name="users_in_groups">
+ <field name="record_id" type="I" size="5">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="user_id" type="I" size="5">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="group_id" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="group_id_uig">
+ <UNIQUE/>
+ <col>group_id</col>
+ <col>user_id</col>
+ </index>
+ <index name="user_id_uig">
+ <col>user_id</col>
+ </index>
+ </table>
+ <table name="votes">
+ <field name="vote_id" type="I" size="11">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="user_id" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="task_id" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="date_time" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ </table>
+ <sql>
+ <query>INSERT INTO groups VALUES (DEFAULT, 'Admin', 'Members have unlimited access to all functionality.', 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1);</query>
+ <query>INSERT INTO groups VALUES (DEFAULT, 'Developers', 'Global Developers for all projects', 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1);</query>
+ <query>INSERT INTO groups VALUES (DEFAULT, 'Reporters', 'Open new tasks / add comments in all projects', 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1);</query>
+ <query>INSERT INTO groups VALUES (DEFAULT, 'Basic', 'Members can login, relying upon Project permissions only', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1);</query>
+ <query>INSERT INTO groups VALUES (DEFAULT, 'Pending', 'Users who are awaiting approval of their accounts.', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);</query>
+ <query>INSERT INTO groups VALUES (DEFAULT, 'Project Managers', 'Permission to do anything related to the Default Project.', 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1);</query>
+ <query>INSERT INTO history VALUES (DEFAULT, 1, 1, 1130024797, 1, '', '', '');</query>
+ <query>INSERT INTO list_category VALUES (DEFAULT, 1, 'Backend / Core', 1, 0, 2, 3);</query>
+ <query>INSERT INTO list_category VALUES (DEFAULT, 0, 'root', 0, 0, 1, 2);</query>
+ <query>INSERT INTO list_category VALUES (DEFAULT, 1, 'root', 0, 0, 1, 4);</query>
+ <query>INSERT INTO list_os VALUES (DEFAULT, 1, 'All', 1, 1);</query>
+ <query>INSERT INTO list_os VALUES (DEFAULT, 1, 'Windows', 2, 1);</query>
+ <query>INSERT INTO list_os VALUES (DEFAULT, 1, 'Linux', 3, 1);</query>
+ <query>INSERT INTO list_os VALUES (DEFAULT, 1, 'Mac OS', 4, 1);</query>
+ <query>INSERT INTO list_resolution VALUES (DEFAULT, 'Not a bug', 1, 1, 0);</query>
+ <query>INSERT INTO list_resolution VALUES (DEFAULT, 'Won''t fix', 2, 1, 0);</query>
+ <query>INSERT INTO list_resolution VALUES (DEFAULT, 'Won''t implement', 3, 1, 0);</query>
+ <query>INSERT INTO list_resolution VALUES (DEFAULT, 'Works for me', 4, 1, 0);</query>
+ <query>INSERT INTO list_resolution VALUES (DEFAULT, 'Deferred', 5, 1, 0);</query>
+ <query>INSERT INTO list_resolution VALUES (DEFAULT, 'Duplicate', 6, 1, 0);</query>
+ <query>INSERT INTO list_resolution VALUES (DEFAULT, 'Fixed', 7, 1, 0);</query>
+ <query>INSERT INTO list_resolution VALUES (DEFAULT, 'Implemented', 8, 1, 0);</query>
+ <query>INSERT INTO list_tasktype VALUES (DEFAULT, 'Bug Report', 1, 1, 0);</query>
+ <query>INSERT INTO list_tasktype VALUES (DEFAULT, 'Feature Request', 2, 1, 0);</query>
+ <query>INSERT INTO list_version VALUES (DEFAULT, 1, 'Development', 1, 1, 2);</query>
+ <query>INSERT INTO list_status (status_name, list_position, show_in_list, project_id) VALUES ('Unconfirmed', 1, 1, 0)</query>
+ <query>INSERT INTO list_status (status_name, list_position, show_in_list, project_id) VALUES ('New', 2, 1, 0)</query>
+ <query>INSERT INTO list_status (status_name, list_position, show_in_list, project_id) VALUES ('Assigned', 3, 1, 0)</query>
+ <query>INSERT INTO list_status (status_name, list_position, show_in_list, project_id) VALUES ('Researching', 4, 1, 0)</query>
+ <query>INSERT INTO list_status (status_name, list_position, show_in_list, project_id) VALUES ('Waiting on Customer', 5, 1, 0)</query>
+ <query>INSERT INTO list_status (status_name, list_position, show_in_list, project_id) VALUES ('Requires testing', 6, 1, 0)</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'fs_ver', '0.9.9');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'jabber_server', '');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'jabber_port', '5222');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'jabber_username', '');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'jabber_password', '');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'anon_group', '4');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'user_notify', '1');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'admin_email', 'flyspray@example.com');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'lang_code', 'en');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'spam_proof', '1');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'default_project', '1');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'dateformat', '');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'dateformat_extended', '');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'anon_reg', '1');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'global_theme', 'CleanFS');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'visible_columns', 'id project category tasktype severity summary status progress');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'smtp_server', '');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'smtp_user', '');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'smtp_pass', '');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'page_title', 'Flyspray::');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'notify_registration', '0');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'jabber_ssl', '0');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'last_update_check', '0');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'cache_feeds', '1');</query>
+ <query>INSERT INTO projects VALUES (DEFAULT, 'Default Project', 'CleanFS', 0, 'Welcome to your first Flyspray project! We hope that Flyspray provides you with many hours of increased productivity. If you have any issues, go to http://flyspray.org/support. You can customise this message by clicking the **Manage Project** link in the menu above...', 1, 'id category tasktype severity summary status progress', 1, 0, '', '', NULL, '0', NULL, NULL, '', 'en', 0, 0, 0, NULL, 'index');</query>
+ <query>INSERT INTO tasks VALUES (1, 1, 1, 1130024797, 1, 0, 0, 0, ' ', 'Sample Task', 'This isn''t a real task. You should close it and start opening some real tasks.', 2, 1, 1, 1, 0, 1, 1, 2, 0, 0, 0, 0, 0, '', '0');</query>
+ <query>INSERT INTO users VALUES (DEFAULT, 'super', '1b3231655cebb7a1f783eddf27d254ca', 'Mr Super User', 'super@example.com', 'super@example.com', 0, 1, 1, '', '', 25, 0, 0, 0);</query>
+ <query>INSERT INTO users_in_groups VALUES (DEFAULT, 1, 1);</query>
+ </sql>
+</schema>
diff --git a/setup/upgrade/0.9.9/rename_columns.php b/setup/upgrade/0.9.9/rename_columns.php
new file mode 100644
index 0000000..07a949a
--- /dev/null
+++ b/setup/upgrade/0.9.9/rename_columns.php
@@ -0,0 +1,14 @@
+<?php
+ /**********************************************************\
+ | This script renames columns, adodb seems to have prob here|
+ \**********************************************************/
+
+$dict = NewDataDictionary($db->dblink);
+
+$sqlarray = $dict->RenameColumnSQL($conf['database']['dbprefix'] . 'tasks', 'attached_to_project', 'project_id', 'TYPE INT(3) NOTNULL DEFAULT 0');
+$dict->ExecuteSQLArray($sqlarray);
+
+$sqlarray = $dict->RenameColumnSQL($conf['database']['dbprefix'] . 'groups', 'belongs_to_project', 'project_id', ' TYPE INT(3) NOTNULL DEFAULT 0');
+$dict->ExecuteSQLArray($sqlarray);
+
+?> \ No newline at end of file
diff --git a/setup/upgrade/0.9.9/upgrade.info b/setup/upgrade/0.9.9/upgrade.info
new file mode 100644
index 0000000..e5ea7e5
--- /dev/null
+++ b/setup/upgrade/0.9.9/upgrade.info
@@ -0,0 +1,44 @@
+[defaultupgrade]
+0="clean_unique.php"
+1="flyspray-begin.xml"
+2="upgrade_assignments.php"
+3="convert_categories.php"
+4="convert_private.php"
+5="add_duplicates.php"
+6="add_searches.php"
+7="rename_columns.php"
+8="flyspray-final.xml"
+9="add_data.php"
+
+[develupgrade]
+1="flyspray-final.xml"
+
+[options]
+
+1="<div><label><input name='replace_resolution' checked='checked' type='checkbox'/> Edit resolution list (strongly recommended for 0.9.8 to 0.9.9)</label></div>"
+
+[fsprefs]
+fs_ver="0.9.7" ; doesn't matter which version
+jabber_server=""
+jabber_port="5222"
+jabber_username=""
+jabber_password=""
+anon_group="0"
+user_notify="1"
+admin_email="flyspray@example.com"
+lang_code="en"
+spam_proof="1"
+default_project="1"
+dateformat=""
+dateformat_extended=""
+anon_reg="1"
+page_title="Flyspray:: "
+notify_registration="0"
+jabber_ssl="0"
+last_update_check="0"
+cache_feeds="1"
+global_theme="CleanFS"
+visible_columns="id project tasktype severity summary status progress"
+smtp_server=""
+smtp_user=""
+smtp_pass="" \ No newline at end of file
diff --git a/setup/upgrade/0.9.9/upgrade_assignments.php b/setup/upgrade/0.9.9/upgrade_assignments.php
new file mode 100644
index 0000000..a9aa53c
--- /dev/null
+++ b/setup/upgrade/0.9.9/upgrade_assignments.php
@@ -0,0 +1,31 @@
+<?php
+ /**********************************************************\
+ | This script moves data from {dbprefix)tasks.assigned_to |
+ | to {dbprefix}assigned. This is to implement multiple |
+ | assignees per task as described in FS#329. It only needs |
+ | to be run once to do the conversion. |
+ \***********************************************************/
+
+$check_sql = $db->query("SELECT task_id, assigned_to
+ FROM {tasks}
+ WHERE assigned_to > '0'");
+
+while ($row = $db->fetchRow($check_sql))
+{
+ $check = $db->query('SELECT assigned_id FROM {assigned} WHERE task_id = ? AND user_id = ?',
+ array($row['task_id'], $row['assigned_to']));
+ if ($db->fetchOne($check)) {
+ continue;
+ }
+
+ $db->query('INSERT INTO {assigned}
+ (task_id, user_id)
+ VALUES (?,?)',
+ array($row['task_id'], $row['assigned_to']));
+
+ $db->query('UPDATE {tasks}
+ SET assigned_to = 0
+ WHERE task_id = ?',
+ array($row['task_id']));
+}
+?>
diff --git a/setup/upgrade/1.0/datadict-postgres.inc.php b/setup/upgrade/1.0/datadict-postgres.inc.php
new file mode 100644
index 0000000..ebcb001
--- /dev/null
+++ b/setup/upgrade/1.0/datadict-postgres.inc.php
@@ -0,0 +1,606 @@
+<?php
+
+/**
+ @version v5.20.9-flyspray 21-Dec-2016
+ @copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
+ @copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
+ Released under both BSD license and Lesser GPL library license.
+ Whenever there is any discrepancy between the two licenses,
+ the BSD license will take precedence.
+
+ Set tabs to 4 for best viewing.
+
+*/
+
+// security - hide paths
+if (!defined('ADODB_DIR')) die();
+
+class ADODB2_postgres extends ADODB_DataDict {
+
+ var $databaseType = 'postgres';
+ var $seqField = false;
+ var $seqPrefix = 'SEQ_';
+ var $addCol = ' ADD COLUMN';
+ var $quote = '"';
+ var $renameTable = 'ALTER TABLE %s RENAME TO %s'; // at least since 7.1
+ var $dropTable = 'DROP TABLE %s CASCADE';
+
+ function metaType($t,$len=-1,$fieldobj=false)
+ {
+ if (is_object($t)) {
+ $fieldobj = $t;
+ $t = $fieldobj->type;
+ $len = $fieldobj->max_length;
+ }
+ $is_serial = is_object($fieldobj) && !empty($fieldobj->primary_key) && !empty($fieldobj->unique) &&
+ !empty($fieldobj->has_default) && substr($fieldobj->default_value,0,8) == 'nextval(';
+
+ switch (strtoupper($t)) {
+ case 'INTERVAL':
+ case 'CHAR':
+ case 'CHARACTER':
+ case 'VARCHAR':
+ case 'NAME':
+ case 'BPCHAR':
+ if ($len <= $this->blobSize) return 'C';
+
+ case 'TEXT':
+ return 'X';
+
+ case 'IMAGE': // user defined type
+ case 'BLOB': // user defined type
+ case 'BIT': // This is a bit string, not a single bit, so don't return 'L'
+ case 'VARBIT':
+ case 'BYTEA':
+ return 'B';
+
+ case 'BOOL':
+ case 'BOOLEAN':
+ return 'L';
+
+ case 'DATE':
+ return 'D';
+
+ case 'TIME':
+ case 'DATETIME':
+ case 'TIMESTAMP':
+ case 'TIMESTAMPTZ':
+ return 'T';
+
+ case 'INTEGER': return !$is_serial ? 'I' : 'R';
+ case 'SMALLINT':
+ case 'INT2': return !$is_serial ? 'I2' : 'R';
+ case 'INT4': return !$is_serial ? 'I4' : 'R';
+ case 'BIGINT':
+ case 'INT8': return !$is_serial ? 'I8' : 'R';
+
+ case 'OID':
+ case 'SERIAL':
+ return 'R';
+
+ case 'FLOAT4':
+ case 'FLOAT8':
+ case 'DOUBLE PRECISION':
+ case 'REAL':
+ return 'F';
+
+ default:
+ return 'N';
+ }
+ }
+
+ function actualType($meta)
+ {
+ switch($meta) {
+ case 'C': return 'VARCHAR';
+ case 'XL':
+ case 'X': return 'TEXT';
+
+ case 'C2': return 'VARCHAR';
+ case 'X2': return 'TEXT';
+
+ case 'B': return 'BYTEA';
+
+ case 'D': return 'DATE';
+ case 'TS':
+ case 'T': return 'TIMESTAMP';
+
+ case 'L': return 'BOOLEAN';
+ case 'I': return 'INTEGER';
+ case 'I1': return 'SMALLINT';
+ case 'I2': return 'INT2';
+ case 'I4': return 'INT4';
+ case 'I8': return 'INT8';
+
+ case 'F': return 'FLOAT8';
+ case 'N': return 'NUMERIC';
+ default:
+ return $meta;
+ }
+ }
+
+ /**
+ * Adding a new Column
+ *
+ * reimplementation of the default function as postgres does NOT allow to set the default in the same statement
+ *
+ * @param string $tabname table-name
+ * @param string $flds column-names and types for the changed columns
+ * @return array with SQL strings
+ */
+ function addColumnSQL($tabname, $flds)
+ {
+ $tabname = $this->tableName($tabname);
+ $sql = array();
+ $not_null = false;
+ list($lines,$pkey) = $this->_genFields($flds);
+ $alter = 'ALTER TABLE ' . $tabname . $this->addCol . ' ';
+ foreach($lines as $v) {
+ if (($not_null = preg_match('/NOT NULL/i',$v))) {
+ $v = preg_replace('/NOT NULL/i','',$v);
+ }
+
+ if (preg_match('/^([^ ]+) .*DEFAULT (\'[^\']+\'|\"[^\"]+\"|[^ ]+)/',$v,$matches)) {
+ list(,$colname,$default) = $matches;
+ $sql[] = $alter . str_replace('DEFAULT '.$default,'',$v);
+ $sql[] = 'UPDATE '.$tabname.' SET '.$colname.'='.$default;
+ $sql[] = 'ALTER TABLE '.$tabname.' ALTER COLUMN '.$colname.' SET DEFAULT ' . $default;
+ }
+ // SERIAL is not a true type in PostgreSQL and is only allowed when creating a new table.
+ // See http://www.postgresql.org/docs/9.4/static/datatype-numeric.html, 8.1.4. Serial Types.
+ elseif (preg_match('/^([^ ]+) .*SERIAL/i',$v,$matches)) {
+ list(,$colname,$default) = $matches;
+ $sql[] = 'CREATE SEQUENCE '.$tabname.'_'.$colname.'_seq';
+ $sql[] = $alter.$colname.' INTEGER';
+ $sql[] = 'ALTER SEQUENCE '.$tabname.'_'.$colname.'_seq OWNED BY '.$tabname.'.'.$colname;
+ $sql[] = 'UPDATE '.$tabname.' SET '.$colname.' = nextval(\''.$tabname.'_'.$colname.'_seq\')';
+ $sql[] = 'ALTER TABLE '.$tabname.' ALTER COLUMN '.$colname.' SET DEFAULT nextval(\''.$tabname.'_'.$colname.'_seq\')';
+ $sql[] = 'ALTER TABLE '.$tabname.' ALTER COLUMN '.$colname.' SET NOT NULL';
+ $not_null = false;
+ } else {
+ $sql[] = $alter . $v;
+ }
+ if ($not_null) {
+ list($colname) = explode(' ',$v);
+ $sql[] = 'ALTER TABLE '.$tabname.' ALTER COLUMN '.$colname.' SET NOT NULL';
+ }
+ }
+ return $sql;
+ }
+
+
+ function dropIndexSQL ($idxname, $tabname = NULL)
+ {
+ return array(sprintf($this->dropIndex, $this->tableName($idxname), $this->tableName($tabname)));
+ }
+
+ /**
+ * Change the definition of one column
+ *
+ * Postgres can't do that on it's own, you need to supply the complete defintion of the new table,
+ * to allow, recreating the table and copying the content over to the new table
+ * @param string $tabname table-name
+ * @param string $flds column-name and type for the changed column
+ * @param string $tableflds complete defintion of the new table, eg. for postgres, default ''
+ * @param array/ $tableoptions options for the new table see createTableSQL, default ''
+ * @return array with SQL strings
+ */
+ /*
+ function alterColumnSQL($tabname, $flds, $tableflds='',$tableoptions='')
+ {
+ if (!$tableflds) {
+ if ($this->debug) ADOConnection::outp("alterColumnSQL needs a complete table-definiton for PostgreSQL");
+ return array();
+ }
+ return $this->_recreate_copy_table($tabname,False,$tableflds,$tableoptions);
+ }*/
+
+ function alterColumnSQL($tabname, $flds, $tableflds='',$tableoptions='')
+ {
+ // Check if alter single column datatype available - works with 8.0+
+ $has_alter_column = 8.0 <= (float) @$this->serverInfo['version'];
+
+ if ($has_alter_column) {
+ $tabname = $this->tableName($tabname);
+ $sql = array();
+ list($lines,$pkey) = $this->_genFields($flds);
+ $set_null = false;
+ foreach($lines as $v) {
+ $alter = 'ALTER TABLE ' . $tabname . $this->alterCol . ' ';
+ if ($not_null = preg_match('/NOT NULL/i',$v)) {
+ $v = preg_replace('/NOT NULL/i','',$v);
+ }
+
+ // SERIAL is not a true type in PostgreSQL and is only allowed when creating a new table.
+ // See http://www.postgresql.org/docs/9.4/static/datatype-numeric.html, 8.1.4. Serial Types.
+ if (preg_match('/SERIAL/i',$v)) {
+ continue;
+ }
+ // this next block doesn't work - there is no way that I can see to
+ // explicitly ask a column to be null using $flds
+ else if ($set_null = preg_match('/NULL/i',$v)) {
+ // if they didn't specify not null, see if they explicitely asked for null
+ // Lookbehind pattern covers the case 'fieldname NULL datatype DEFAULT NULL'
+ // only the first NULL should be removed, not the one specifying
+ // the default value
+ $v = preg_replace('/(?<!DEFAULT)\sNULL/i','',$v);
+ }
+
+ if (preg_match('/^([^ ]+) .*DEFAULT (\'[^\']+\'|\"[^\"]+\"|[^ ]+)/',$v,$matches)) {
+ $existing = $this->metaColumns($tabname);
+ list(,$colname,$default) = $matches;
+ $alter .= $colname;
+ if ($this->connection) {
+ $old_coltype = $this->connection->metaType($existing[strtoupper($colname)]);
+ }
+ else {
+ $old_coltype = $t;
+ }
+ $v = preg_replace('/^' . preg_quote($colname) . '\s/', '', $v);
+ $t = trim(str_replace('DEFAULT '.$default,'',$v));
+
+ // Type change from bool to int
+ if ( $old_coltype == 'L' && $t == 'INTEGER' ) {
+ $sql[] = $alter . ' DROP DEFAULT';
+ $sql[] = $alter . " TYPE $t USING ($colname::BOOL)::INT";
+ $sql[] = $alter . " SET DEFAULT $default";
+ }
+ // Type change from int to bool
+ else if ( $old_coltype == 'I' && $t == 'BOOLEAN' ) {
+ if( strcasecmp('NULL', trim($default)) != 0 ) {
+ $default = $this->connection->qstr($default);
+ }
+ $sql[] = $alter . ' DROP DEFAULT';
+ $sql[] = $alter . " TYPE $t USING CASE WHEN $colname = 0 THEN false ELSE true END";
+ $sql[] = $alter . " SET DEFAULT $default";
+ }
+ // Any other column types conversion
+ else {
+ $sql[] = $alter . " TYPE $t";
+ $sql[] = $alter . " SET DEFAULT $default";
+ }
+
+ }
+ else {
+ // drop default?
+ preg_match ('/^\s*(\S+)\s+(.*)$/',$v,$matches);
+ list (,$colname,$rest) = $matches;
+ $alter .= $colname;
+ $sql[] = $alter . ' TYPE ' . $rest;
+ }
+
+# list($colname) = explode(' ',$v);
+ if ($not_null) {
+ // this does not error out if the column is already not null
+ $sql[] = $alter . ' SET NOT NULL';
+ }
+ if ($set_null) {
+ // this does not error out if the column is already null
+ $sql[] = $alter . ' DROP NOT NULL';
+ }
+ }
+ return $sql;
+ }
+
+ // does not have alter column
+ if (!$tableflds) {
+ if ($this->debug) ADOConnection::outp("AlterColumnSQL needs a complete table-definiton for PostgreSQL");
+ return array();
+ }
+ return $this->_recreate_copy_table($tabname,False,$tableflds,$tableoptions);
+ }
+
+ /**
+ * Drop one column
+ *
+ * Postgres < 7.3 can't do that on it's own, you need to supply the complete defintion of the new table,
+ * to allow, recreating the table and copying the content over to the new table
+ * @param string $tabname table-name
+ * @param string $flds column-name and type for the changed column
+ * @param string $tableflds complete defintion of the new table, eg. for postgres, default ''
+ * @param array/ $tableoptions options for the new table see CreateTableSQL, default ''
+ * @return array with SQL strings
+ */
+ function dropColumnSQL($tabname, $flds, $tableflds='',$tableoptions='')
+ {
+ $has_drop_column = 7.3 <= (float) @$this->serverInfo['version'];
+ if (!$has_drop_column && !$tableflds) {
+ if ($this->debug) ADOConnection::outp("DropColumnSQL needs complete table-definiton for PostgreSQL < 7.3");
+ return array();
+ }
+ if ($has_drop_column) {
+ return ADODB_DataDict::dropColumnSQL($tabname, $flds);
+ }
+ return $this->_recreate_copy_table($tabname,$flds,$tableflds,$tableoptions);
+ }
+
+ /**
+ * Save the content into a temp. table, drop and recreate the original table and copy the content back in
+ *
+ * We also take care to set the values of the sequenz and recreate the indexes.
+ * All this is done in a transaction, to not loose the content of the table, if something went wrong!
+ * @internal
+ * @param string $tabname table-name
+ * @param string $dropflds column-names to drop
+ * @param string $tableflds complete defintion of the new table, eg. for postgres
+ * @param array/string $tableoptions options for the new table see CreateTableSQL, default ''
+ * @return array with SQL strings
+ */
+ function _recreate_copy_table($tabname,$dropflds,$tableflds,$tableoptions='')
+ {
+ if ($dropflds && !is_array($dropflds)) $dropflds = explode(',',$dropflds);
+ $copyflds = array();
+ foreach($this->metaColumns($tabname) as $fld) {
+ if (!$dropflds || !in_array($fld->name,$dropflds)) {
+ // we need to explicit convert varchar to a number to be able to do an AlterColumn of a char column to a nummeric one
+ if (preg_match('/'.$fld->name.' (I|I2|I4|I8|N|F)/i',$tableflds,$matches) &&
+ in_array($fld->type,array('varchar','char','text','bytea'))) {
+ $copyflds[] = "to_number($fld->name,'S9999999999999D99')";
+ } else {
+ $copyflds[] = $fld->name;
+ }
+ // identify the sequence name and the fld its on
+ if ($fld->primary_key && $fld->has_default &&
+ preg_match("/nextval\('([^']+)'::text\)/",$fld->default_value,$matches)) {
+ $seq_name = $matches[1];
+ $seq_fld = $fld->name;
+ }
+ }
+ }
+ $copyflds = implode(', ',$copyflds);
+
+ $tempname = $tabname.'_tmp';
+ $aSql[] = 'BEGIN'; // we use a transaction, to make sure not to loose the content of the table
+ $aSql[] = "SELECT * INTO TEMPORARY TABLE $tempname FROM $tabname";
+ $aSql = array_merge($aSql,$this->dropTableSQL($tabname));
+ $aSql = array_merge($aSql,$this->createTableSQL($tabname,$tableflds,$tableoptions));
+ $aSql[] = "INSERT INTO $tabname SELECT $copyflds FROM $tempname";
+ if ($seq_name && $seq_fld) { // if we have a sequence we need to set it again
+ $seq_name = $tabname.'_'.$seq_fld.'_seq'; // has to be the name of the new implicit sequence
+ $aSql[] = "SELECT setval('$seq_name',MAX($seq_fld)) FROM $tabname";
+ }
+ $aSql[] = "DROP TABLE $tempname";
+ // recreate the indexes, if they not contain one of the droped columns
+ foreach($this->metaIndexes($tabname) as $idx_name => $idx_data)
+ {
+ if (substr($idx_name,-5) != '_pkey' && (!$dropflds || !count(array_intersect($dropflds,$idx_data['columns'])))) {
+ $aSql = array_merge($aSql,$this->createIndexSQL($idx_name,$tabname,$idx_data['columns'],
+ $idx_data['unique'] ? array('UNIQUE') : False));
+ }
+ }
+ $aSql[] = 'COMMIT';
+ return $aSql;
+ }
+
+ function dropTableSQL($tabname)
+ {
+ $sql = ADODB_DataDict::dropTableSQL($tabname);
+
+ $drop_seq = $this->_dropAutoIncrement($tabname);
+ if ($drop_seq) $sql[] = $drop_seq;
+
+ return $sql;
+ }
+
+ // return string must begin with space
+ function _createSuffix($fname, &$ftype, $fnotnull,$fdefault,$fautoinc,$fconstraint,$funsigned)
+ {
+ if ($fautoinc) {
+ $ftype = 'SERIAL';
+ return '';
+ }
+ $suffix = '';
+ if (strlen($fdefault)) $suffix .= " DEFAULT $fdefault";
+ if ($fnotnull) $suffix .= ' NOT NULL';
+ if ($fconstraint) $suffix .= ' '.$fconstraint;
+ return $suffix;
+ }
+
+ // search for a sequece for the given table (asumes the seqence-name contains the table-name!)
+ // if yes return sql to drop it
+ // this is still necessary if postgres < 7.3 or the SERIAL was created on an earlier version!!!
+ function _dropAutoIncrement($tabname)
+ {
+ $tabname = $this->connection->quote('%'.$tabname.'%');
+
+ $seq = $this->connection->getOne("SELECT relname FROM pg_class WHERE NOT relname ~ 'pg_.*' AND relname LIKE $tabname AND relkind='S'");
+
+ // check if a tables depends on the sequenz and it therefor cant and dont need to be droped separatly
+ if (!$seq || $this->connection->getOne("SELECT relname FROM pg_class JOIN pg_depend ON pg_class.relfilenode=pg_depend.objid WHERE relname='$seq' AND relkind='S' AND deptype='i'")) {
+ return False;
+ }
+ return "DROP SEQUENCE ".$seq;
+ }
+
+ function renameTableSQL($tabname,$newname)
+ {
+ if (!empty($this->schema)) {
+ $rename_from = $this->tableName($tabname);
+ $schema_save = $this->schema;
+ $this->schema = false;
+ $rename_to = $this->tableName($newname);
+ $this->schema = $schema_save;
+ return array (sprintf($this->renameTable, $rename_from, $rename_to));
+ }
+
+ return array (sprintf($this->renameTable, $this->tableName($tabname),$this->tableName($newname)));
+ }
+
+ /*
+ CREATE [ [ LOCAL ] { TEMPORARY | TEMP } ] TABLE table_name (
+ { column_name data_type [ DEFAULT default_expr ] [ column_constraint [, ... ] ]
+ | table_constraint } [, ... ]
+ )
+ [ INHERITS ( parent_table [, ... ] ) ]
+ [ WITH OIDS | WITHOUT OIDS ]
+ where column_constraint is:
+ [ CONSTRAINT constraint_name ]
+ { NOT NULL | NULL | UNIQUE | PRIMARY KEY |
+ CHECK (expression) |
+ REFERENCES reftable [ ( refcolumn ) ] [ MATCH FULL | MATCH PARTIAL ]
+ [ ON DELETE action ] [ ON UPDATE action ] }
+ [ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ]
+ and table_constraint is:
+ [ CONSTRAINT constraint_name ]
+ { UNIQUE ( column_name [, ... ] ) |
+ PRIMARY KEY ( column_name [, ... ] ) |
+ CHECK ( expression ) |
+ FOREIGN KEY ( column_name [, ... ] ) REFERENCES reftable [ ( refcolumn [, ... ] ) ]
+ [ MATCH FULL | MATCH PARTIAL ] [ ON DELETE action ] [ ON UPDATE action ] }
+ [ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ]
+ */
+
+
+ /*
+ CREATE [ UNIQUE ] INDEX index_name ON table
+[ USING acc_method ] ( column [ ops_name ] [, ...] )
+[ WHERE predicate ]
+CREATE [ UNIQUE ] INDEX index_name ON table
+[ USING acc_method ] ( func_name( column [, ... ]) [ ops_name ] )
+[ WHERE predicate ]
+ */
+ function _indexSQL($idxname, $tabname, $flds, $idxoptions)
+ {
+ $sql = array();
+
+ if ( isset($idxoptions['REPLACE']) || isset($idxoptions['DROP']) ) {
+ $sql[] = sprintf ($this->dropIndex, $idxname, $tabname);
+ if ( isset($idxoptions['DROP']) )
+ return $sql;
+ }
+
+ if ( empty ($flds) ) {
+ return $sql;
+ }
+
+ $unique = isset($idxoptions['UNIQUE']) ? ' UNIQUE' : '';
+
+ $s = 'CREATE' . $unique . ' INDEX ' . $idxname . ' ON ' . $tabname . ' ';
+
+ if (isset($idxoptions['HASH']))
+ $s .= 'USING HASH ';
+
+ if ( isset($idxoptions[$this->upperName]) )
+ $s .= $idxoptions[$this->upperName];
+
+ if ( is_array($flds) )
+ $flds = implode(', ',$flds);
+ $s .= '(' . $flds . ')';
+ $sql[] = $s;
+
+ return $sql;
+ }
+
+ function _getSize($ftype, $ty, $fsize, $fprec)
+ {
+ if (strlen($fsize) && $ty != 'X' && $ty != 'B' && $ty != 'I' && strpos($ftype,'(') === false) {
+ $ftype .= "(".$fsize;
+ if (strlen($fprec)) $ftype .= ",".$fprec;
+ $ftype .= ')';
+ }
+ return $ftype;
+ }
+
+ /**
+ "Florian Buzin [ easywe ]" <florian.buzin#easywe.de>
+
+ This function changes/adds new fields to your table. You don't
+ have to know if the col is new or not. It will check on its own.
+ */
+ function changeTableSQL($tablename, $flds, $tableoptions = false, $dropOldFlds=false)
+ {
+ global $ADODB_FETCH_MODE;
+
+ $save = $ADODB_FETCH_MODE;
+ $ADODB_FETCH_MODE = ADODB_FETCH_ASSOC;
+ if ($this->connection->fetchMode !== false) $savem = $this->connection->setFetchMode(false);
+
+ // check table exists
+ $save_handler = $this->connection->raiseErrorFn;
+ $this->connection->raiseErrorFn = '';
+ $cols = $this->metaColumns($tablename);
+ $this->connection->raiseErrorFn = $save_handler;
+
+ if (isset($savem)) $this->connection->setFetchMode($savem);
+ $ADODB_FETCH_MODE = $save;
+
+ if ( empty($cols)) {
+ return $this->createTableSQL($tablename, $flds, $tableoptions);
+ }
+
+ $addedcols = array();
+ $modifiedcols = array();
+
+ if (is_array($flds)) {
+ // Cycle through the update fields, comparing
+ // existing fields to fields to update.
+ // if the Metatype and size is exactly the
+ // same, ignore - by Mark Newham
+ foreach($flds as $k=>$v) {
+ if ( isset($cols[$k]) && is_object($cols[$k]) ) {
+ // If already not allowing nulls, then don't change
+ $obj = $cols[$k];
+ if (isset($obj->not_null) && $obj->not_null)
+ $v = str_replace('NOT NULL','',$v);
+ if (isset($obj->auto_increment) && $obj->auto_increment && empty($v['AUTOINCREMENT']))
+ $v = str_replace('AUTOINCREMENT','',$v);
+
+ $c = $cols[$k];
+ $ml = $c->max_length;
+ $mt = $this->metaType($c->type,$ml);
+
+ if (isset($c->scale)) $sc = $c->scale;
+ else $sc = 99; // always force change if scale not known.
+
+ if ($sc == -1) $sc = false;
+ list($fsize, $fprec) = $this->_getSizePrec($v['SIZE']);
+
+ if ($ml == -1) $ml = '';
+ if ($mt == 'X') $ml = $v['SIZE'];
+ if (($mt != $v['TYPE']) || ($ml != $fsize || $sc != $fprec) || (isset($v['AUTOINCREMENT']) && $v['AUTOINCREMENT'] != $obj->auto_increment)) {
+ $modifiedcols[$k] = $v;
+ }
+ } else {
+ $addedcols[$k] = $v;
+ }
+ }
+ }
+
+
+ $sql = array();
+ $sql = $this->addColumnSQL($tablename, $addedcols);
+
+ // already exists, alter table instead
+ list($lines,$pkey,$idxs) = $this->_genFields($modifiedcols);
+ // genfields can return FALSE at times
+ if ($lines == null) $lines = array();
+
+ $holdflds = array();
+ foreach ( $lines as $id => $v ) {
+ if ( isset($cols[$id]) && is_object($cols[$id]) ) {
+
+ $flds = lens_ParseArgs($v,',');
+
+ // We are trying to change the size of the field, if not allowed, simply ignore the request.
+ // $flds[1] holds the type, $flds[2] holds the size -postnuke addition
+ if ($flds && in_array(strtoupper(substr($flds[0][1],0,4)),$this->invalidResizeTypes4)
+ && (isset($flds[0][2]) && is_numeric($flds[0][2]))) {
+ if ($this->debug) ADOConnection::outp(sprintf("<h3>%s cannot be changed to %s currently</h3>", $flds[0][0], $flds[0][1]));
+ #echo "<h3>$this->alterCol cannot be changed to $flds currently</h3>";
+ continue;
+ }
+ $holdflds[] = $modifiedcols[$id];
+ }
+ }
+ $modifiedcols = $holdflds;
+ $sql += $this->alterColumnSQL($tablename, $modifiedcols);
+
+ if ($dropOldFlds) {
+ $alter = 'ALTER TABLE ' . $this->tableName($tablename);
+ foreach ( $cols as $id => $v )
+ if ( !isset($lines[$id]) )
+ $sql[] = $alter . $this->dropCol . ' ' . $v->name;
+ }
+ return $sql;
+ }
+}
diff --git a/setup/upgrade/1.0/flyspray-install.xml b/setup/upgrade/1.0/flyspray-install.xml
new file mode 100644
index 0000000..ee7102b
--- /dev/null
+++ b/setup/upgrade/1.0/flyspray-install.xml
@@ -0,0 +1,1373 @@
+<?xml version="1.0"?>
+<schema version="0.3">
+ <table name="user_emails">
+ <descr>multiple addresses for users. subject to change in FS1.1+!</descr>
+ <field name="id" type="I" size="5"></field>
+ <field name="email_address" type="C" size="100"></field>
+ <field name="oauth_uid" type="C" size="255">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="oauth_provider" type="C" size="10">
+ <NOTNULL/>
+ <DEFAULT value=""/>
+ </field>
+ </table>
+ <table name="tags">
+ <desc>Do not use this table. pre FS1.0-beta table</desc>
+ <field name="task_id" type="I" size="5"></field>
+ <field name="tag" type="C" size="100"></field>
+ </table>
+ <table name="admin_requests">
+ <descr>Pending requests for admins and PMs to attend to</descr>
+ <field name="request_id" type="I" size="5">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="project_id" type="I" size="5">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="task_id" type="I" size="5">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="submitted_by" type="I" size="5">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="request_type" type="I" size="2">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="reason_given" type="X">
+ <NOTNULL/>
+ </field>
+ <field name="time_submitted" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="resolved_by" type="I" size="5">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="time_resolved" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="deny_reason" type="C" size="255" />
+ <index name="resolved_project">
+ <col>resolved_by</col>
+ <col>project_id</col>
+ </index>
+ </table>
+ <table name="assigned">
+ <descr>Who is assigned what task</descr>
+ <field name="assigned_id" type="I" size="10">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="task_id" type="I" size="10">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="user_id" type="I" size="5">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="task_user">
+ <UNIQUE/>
+ <col>task_id</col>
+ <col>user_id</col>
+ </index>
+ </table>
+ <table name="attachments">
+ <descr>List the names and locations of files attached to tasks</descr>
+ <field name="attachment_id" type="I" size="5">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="task_id" type="I" size="10">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="comment_id" type="I" size="10">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="orig_name" type="C" size="255">
+ <NOTNULL/>
+ </field>
+ <field name="file_name" type="C" size="30">
+ <NOTNULL/>
+ </field>
+ <field name="file_type" type="C" size="255">
+ <NOTNULL/>
+ </field>
+ <field name="file_size" type="I" size="20">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="added_by" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="date_added" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="task_id_attachments">
+ <col>task_id</col>
+ <col>comment_id</col>
+ </index>
+ </table>
+ <table name="cache">
+ <descr>Table to cache RSS/Atom feeds</descr>
+ <field name="id" type="I" size="6">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="type" type="C" size="4">
+ <NOTNULL/>
+ </field>
+ <field name="content" type="XL">
+ <NOTNULL/>
+ </field>
+ <field name="topic" type="I" size="11">
+ <NOTNULL/>
+ </field>
+ <field name="last_updated" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="project_id" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="max_items" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="cache_type">
+ <UNIQUE/>
+ <col>type</col>
+ <col>topic</col>
+ <col>project_id</col>
+ <col>max_items</col>
+ </index>
+ <index name="cache_type_topic">
+ <col>type</col>
+ <col>topic</col>
+ </index>
+ </table>
+ <table name="comments">
+ <descr>task comments</descr>
+ <field name="comment_id" type="I" size="10">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="task_id" type="I" size="10">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="date_added" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="user_id" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="comment_text" type="X">
+ <NOTNULL/>
+ </field>
+ <field name="last_edited_time" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="task_id_comments">
+ <col>task_id</col>
+ </index>
+ <index name="user_id_comments">
+ <col>user_id</col>
+ </index>
+ </table>
+ <table name="dependencies">
+ <descr>Task inter-dependencies</descr>
+ <field name="depend_id" type="I" size="10">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="task_id" type="I" size="10">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="dep_task_id" type="I" size="10">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="task_id_deps">
+ <UNIQUE/>
+ <col>task_id</col>
+ <col>dep_task_id</col>
+ </index>
+ </table>
+ <table name="effort">
+ <descr>log of time spent on tasks</descr>
+ <field name="effort_id" type="I" size="10">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="task_id" type="I" size="10">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="date_added" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="user_id" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="start_timestamp" type="I" size="11"/>
+ <field name="end_timestamp" type="I" size="11"/>
+ <field name="effort" type="I" size="15">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="task_id_effort">
+ <col>task_id</col>
+ </index>
+ </table>
+ <table name="groups">
+ <descr>User Groups for the Flyspray bug killer</descr>
+ <field name="group_id" type="I" size="3">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="group_name" type="C" size="20">
+ <NOTNULL/>
+ </field>
+ <field name="group_desc" type="C" size="150">
+ <NOTNULL/>
+ </field>
+ <field name="project_id" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="is_admin" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="manage_project" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="view_tasks" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="open_new_tasks" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="modify_own_tasks" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="modify_all_tasks" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="view_comments" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="add_comments" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="edit_comments" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="edit_own_comments" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="delete_comments" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="create_attachments" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="delete_attachments" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="view_history" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="close_own_tasks" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="close_other_tasks" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="assign_to_self" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="assign_others_to_self" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="add_to_assignees" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="view_reports" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="add_votes" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="edit_assignments" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="show_as_assignees" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="view_estimated_effort" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="view_current_effort_done" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="track_effort" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="group_open" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="add_multiple_tasks" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="view_roadmap" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="view_own_tasks" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="view_groups_tasks" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="group_name">
+ <UNIQUE/>
+ <col>group_name</col>
+ <col>project_id</col>
+ </index>
+ <index name="belongs_to_project">
+ <col>project_id</col>
+ </index>
+ </table>
+ <table name="history">
+ <descr>log of Flyspray activities</descr>
+ <field name="history_id" type="I" size="10">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="task_id" type="I" size="10">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="user_id" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="event_date" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="event_type" type="I" size="2">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="field_changed" type="C" size="50">
+ <NOTNULL/>
+ </field>
+ <field name="old_value" type="X" />
+ <field name="new_value" type="X" />
+ <index name="idx_task_id">
+ <col>task_id</col>
+ </index>
+ <index name="idx_event_date">
+ <col>event_date</col>
+ </index>
+ <index name="idx_event_type">
+ <col>event_type</col>
+ </index>
+ </table>
+ <table name="list_category">
+ <descr>hierarchic task categories</descr>
+ <field name="category_id" type="I" size="3">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="project_id" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="category_name" type="C" size="40">
+ <NOTNULL/>
+ </field>
+ <field name="show_in_list" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="category_owner" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="lft" type="I" size="10">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ <UNSIGNED/>
+ </field>
+ <field name="rgt" type="I" size="10">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ <UNSIGNED/>
+ </field>
+ <index name="project_id_cat">
+ <col>project_id</col>
+ </index>
+ </table>
+ <table name="list_os">
+ <descr>Operating system list for the Flyspray bug killer</descr>
+ <field name="os_id" type="I" size="3">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="project_id" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="os_name" type="C" size="40">
+ <NOTNULL/>
+ </field>
+ <field name="list_position" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="show_in_list" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="project_id_os">
+ <UNIQUE/>
+ <col>project_id</col>
+ <col>os_name</col>
+ </index>
+ </table>
+ <table name="list_resolution">
+ <descr>task close reasons</descr>
+ <field name="resolution_id" type="I" size="3">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="resolution_name" type="C" size="40">
+ <NOTNULL/>
+ </field>
+ <field name="list_position" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="show_in_list" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="project_id" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="project_id_res">
+ <UNIQUE/>
+ <col>project_id</col>
+ <col>resolution_name</col>
+ </index>
+ </table>
+ <table name="list_status">
+ <descr>List of possible task statuses</descr>
+ <field name="status_id" type="I" size="3">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="status_name" type="C" size="40">
+ <NOTNULL/>
+ </field>
+ <field name="list_position" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="show_in_list" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="project_id" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="project_id_status">
+ <UNIQUE/>
+ <col>project_id</col>
+ <col>status_name</col>
+ </index>
+ </table>
+ <table name="list_tag">
+ <descr>definition of tags/labels for tasks</descr>
+ <field name="tag_id" type="I" size="5">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="project_id" type="I" size="5">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="tag_name" type="C" size="40">
+ <NOTNULL/>
+ </field>
+ <field name="list_position" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="show_in_list" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="class" type="C" size="100"/>
+ <index name="tag_name">
+ <UNIQUE/>
+ <col>project_id</col>
+ <col>tag_name</col>
+ </index>
+ </table>
+ <table name="list_tasktype">
+ <descr>List of possible task types</descr>
+ <field name="tasktype_id" type="I" size="3">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="tasktype_name" type="C" size="40">
+ <NOTNULL/>
+ </field>
+ <field name="list_position" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="show_in_list" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="project_id" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="project_id_tt">
+ <UNIQUE/>
+ <col>project_id</col>
+ <col>tasktype_name</col>
+ </index>
+ </table>
+ <table name="list_version">
+ <descr>list of project versions/milestones/software release versions</descr>
+ <field name="version_id" type="I" size="3">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="project_id" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="version_name" type="C" size="40">
+ <NOTNULL/>
+ </field>
+ <field name="list_position" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="show_in_list" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="version_tense" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="project_id_version_name">
+ <UNIQUE/>
+ <col>project_id</col>
+ <col>version_name</col>
+ </index>
+ <index name="project_id_version">
+ <col>project_id</col>
+ <col>version_tense</col>
+ </index>
+ </table>
+ <table name="notification_messages">
+ <descr>Notification body and subject</descr>
+ <field name="message_id" type="I" size="10">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="message_subject" type="X">
+ <NOTNULL/>
+ </field>
+ <field name="message_body" type="X">
+ <NOTNULL/>
+ </field>
+ <field name="time_created" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ </table>
+ <table name="notification_recipients">
+ <descr>Notification recipient list</descr>
+ <field name="recipient_id" type="I" size="10">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="message_id" type="I" size="10">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="notify_method" type="C" size="1">
+ <NOTNULL/>
+ </field>
+ <field name="notify_address" type="C" size="100">
+ <NOTNULL/>
+ </field>
+ </table>
+ <table name="notifications">
+ <descr>Extra task notification registrations are stored here</descr>
+ <field name="notify_id" type="I" size="10">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="task_id" type="I" size="10">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="user_id" type="I" size="5">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="task_id_notifs">
+ <UNIQUE/>
+ <col>task_id</col>
+ <col>user_id</col>
+ </index>
+ </table>
+ <table name="prefs">
+ <descr>global settings of Flyspray</descr>
+ <field name="pref_id" type="I" size="1">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="pref_name" type="C" size="40">
+ <NOTNULL/>
+ </field>
+ <field name="pref_value" type="X" />
+ </table>
+ <table name="projects">
+ <descr>project settings</descr>
+ <field name="project_id" type="I" size="3">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="project_title" type="C" size="100">
+ <NOTNULL/>
+ </field>
+ <field name="theme_style" type="C" size="20">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="default_cat_owner" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="intro_message" type="X">
+ <NOTNULL/>
+ <DEFAULT value=""/>
+ </field>
+ <field name="project_is_active" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="visible_columns" type="C" size="255">
+ <NOTNULL/>
+ </field>
+ <field name="visible_fields" type="C" size="255">
+ <NOTNULL/>
+ </field>
+ <field name="others_view" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="others_viewroadmap" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="anon_open" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="notify_email" type="X">
+ <NOTNULL/>
+ <DEFAULT value=""/>
+ </field>
+ <field name="notify_jabber" type="X">
+ <NOTNULL/>
+ <DEFAULT value=""/>
+ </field>
+ <field name="notify_reply" type="X">
+ <NOTNULL/>
+ <DEFAULT value=""/>
+ </field>
+ <field name="notify_types" type="C" size="100">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="feed_img_url" type="X">
+ <NOTNULL/>
+ <DEFAULT value=""/>
+ </field>
+ <field name="feed_description" type="X">
+ <NOTNULL/>
+ <DEFAULT value=""/>
+ </field>
+ <field name="notify_subject" type="C" size="100">
+ <NOTNULL/>
+ <DEFAULT value=""/>
+ </field>
+ <field name="lang_code" type="C" size="10">
+ <NOTNULL/>
+ </field>
+ <field name="comment_closed" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="auto_assign" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="last_updated" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="default_task" type="X">
+ <NOTNULL/>
+ </field>
+ <field name="default_entry" type="C" size="8">
+ <NOTNULL/>
+ <DEFAULT value="index"/>
+ </field>
+ <field name="disp_intro" type="I" size="1">
+ <DEFAULT value="0"/>
+ </field>
+ <field name="use_effort_tracking" type="I" size="1">
+ <DEFAULT value="0"/>
+ </field>
+ <field name="default_due_version" type="C" size="40">
+ <NOTNULL/>
+ <DEFAULT value="Undecided"/>
+ </field>
+ <field name="pages_intro_msg" type="C" size="80">
+ <NOTNULL/>
+ <DEFAULT value="index"/>
+ </field>
+ <field name="hours_per_manday" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="estimated_effort_format" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="current_effort_done_format" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="default_order_by" type="C" size="100">
+ <NOTNULL/>
+ <DEFAULT value="id"/>
+ </field>
+ <field name="default_order_by_dir" type="C" size="5">
+ <NOTNULL/>
+ <DEFAULT value="desc"/>
+ </field>
+ <field name="custom_style" type="C" size="32">
+ </field>
+ <field name="freetagging" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="1"/>>
+ </field>
+ </table>
+ <table name="registrations">
+ <descr>table for yet unconfirmed user registrations</descr>
+ <field name="reg_id" type="I" size="10">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="reg_time" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="confirm_code" type="C" size="20">
+ <NOTNULL/>
+ </field>
+ <field name="user_name" type="C" size="32">
+ <NOTNULL/>
+ </field>
+ <field name="real_name" type="C" size="100">
+ <NOTNULL/>
+ </field>
+ <field name="email_address" type="C" size="100">
+ <NOTNULL/>
+ </field>
+ <field name="jabber_id" type="C" size="100">
+ <NOTNULL/>
+ </field>
+ <field name="notify_type" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="magic_url" type="C" size="40">
+ <NOTNULL/>
+ </field>
+ <field name="time_zone" type="I" size="6">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ </table>
+ <table name="related">
+ <descr>contains loose task relations to another task or task duplicates</descr>
+ <field name="related_id" type="I" size="10">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="this_task" type="I" size="10">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="related_task" type="I" size="10">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="is_duplicate" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="this_task">
+ <UNIQUE/>
+ <col>this_task</col>
+ <col>related_task</col>
+ <col>is_duplicate</col>
+ </index>
+ </table>
+ <table name="reminders">
+ <descr>scheduled task reminders</descr>
+ <field name="reminder_id" type="I" size="10">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="task_id" type="I" size="10">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="to_user_id" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="from_user_id" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="start_time" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="how_often" type="I" size="12">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="last_sent" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="reminder_message" type="X">
+ <NOTNULL/>
+ </field>
+ </table>
+ <table name="searches">
+ <descr>Saves custom searches of users</descr>
+ <field name="id" type="I" size="11">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="user_id" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="name" type="C" size="50">
+ <NOTNULL/>
+ </field>
+ <field name="search_string" type="X">
+ <NOTNULL/>
+ </field>
+ <field name="time" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ </table>
+ <table name="tasks">
+ <desc>main table for storing tasks</desc>
+ <field name="task_id" type="I" size="10">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="project_id" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="task_type" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="date_opened" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="opened_by" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="is_closed" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="date_closed" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="closed_by" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="closure_comment" type="X">
+ <NOTNULL/>
+ </field>
+ <field name="item_summary" type="C" size="100">
+ <NOTNULL/>
+ </field>
+ <field name="detailed_desc" type="X">
+ <NOTNULL/>
+ </field>
+ <field name="item_status" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="resolution_reason" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="1"/>
+ </field>
+ <field name="product_category" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="product_version" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="closedby_version" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="operating_system" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="task_severity" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="task_priority" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="last_edited_by" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="last_edited_time" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="percent_complete" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="mark_private" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="due_date" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="anon_email" type="C" size="100">
+ <NOTNULL/>
+ <DEFAULT value=""/>
+ </field>
+ <field name="task_token" type="C" size="32">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="supertask_id" type="I" size="10">
+ <DEFAULT value="0"/>
+ </field>
+ <field name="list_order" type="I" size="3">
+ <DEFAULT value="0"/>
+ </field>
+ <field name="estimated_effort" type="I" size="3">
+ <DEFAULT value="0"/>
+ </field>
+ <index name="attached_to_project">
+ <col>project_id</col>
+ </index>
+ <index name="task_severity">
+ <col>task_severity</col>
+ </index>
+ <index name="task_type">
+ <col>task_type</col>
+ </index>
+ <index name="product_category">
+ <col>product_category</col>
+ </index>
+ <index name="item_status">
+ <col>item_status</col>
+ </index>
+ <index name="is_closed">
+ <col>is_closed</col>
+ </index>
+ <index name="closedby_version">
+ <col>closedby_version</col>
+ </index>
+ <index name="due_date">
+ <col>due_date</col>
+ </index>
+ <index name="task_project_super">
+ <col>project_id</col>
+ <col>supertask_id</col>
+ </index>
+ <index name="task_super">
+ <col>supertask_id</col>
+ <col>task_id</col>
+ <col>project_id</col>
+ </index>
+ </table>
+ <table name="task_tag">
+ <desc>join table to add tags/labels to tasks</desc>
+ <field name="task_id" type="I" size="5">
+ <KEY/>
+ </field>
+ <field name="tag_id" type="I" size="5">
+ <KEY/>
+ </field>
+ <index name="task_id_tag">
+ <UNIQUE/>
+ <col>task_id</col>
+ <col>tag_id</col>
+ </index>
+ </table>
+ <table name="users">
+ <descr>user accounts of Flyspray</descr>
+ <field name="user_id" type="I" size="3">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="user_name" type="C" size="32">
+ <NOTNULL/>
+ </field>
+ <field name="user_pass" type="C" size="128"/>
+ <field name="real_name" type="C" size="100">
+ <NOTNULL/>
+ </field>
+ <field name="jabber_id" type="C" size="100">
+ <NOTNULL/>
+ </field>
+ <field name="email_address" type="C" size="100">
+ <NOTNULL/>
+ </field>
+ <field name="notify_type" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="notify_own" type="I" size="6">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="account_enabled" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="dateformat" type="C" size="30">
+ <NOTNULL/>
+ <DEFAULT value=""/>
+ </field>
+ <field name="dateformat_extended" type="C" size="30">
+ <NOTNULL/>
+ <DEFAULT value=""/>
+ </field>
+ <field name="magic_url" type="C" size="40">
+ <NOTNULL/>
+ <DEFAULT value=""/>
+ </field>
+ <field name="tasks_perpage" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="register_date" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="time_zone" type="I" size="6">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="login_attempts" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="lock_until" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="lang_code" type="C" size="10">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="oauth_uid" type="C" size="255">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="oauth_provider" type="C" size="10">
+ <NOTNULL/>
+ <DEFAULT value=""/>
+ </field>
+ <field name="profile_image" type="C" size="100">
+ <NOTNULL/>
+ <DEFAULT value=""/>
+ </field>
+ <field name="hide_my_email" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="notify_online" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="last_login" type="I" size="11">
+ <descr>last login of a user</descr>
+ <NULL/>
+ </field>
+ <index name="user_name">
+ <UNIQUE/>
+ <col>user_name</col>
+ </index>
+ </table>
+ <table name="users_in_groups">
+ <descr>Which users are in which groups</descr>
+ <field name="record_id" type="I" size="5">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="user_id" type="I" size="5">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="group_id" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="group_id_uig">
+ <UNIQUE/>
+ <col>group_id</col>
+ <col>user_id</col>
+ </index>
+ <index name="user_id_uig">
+ <col>user_id</col>
+ </index>
+ </table>
+ <table name="votes">
+ <descr>votes for tasks</descr>
+ <field name="vote_id" type="I" size="11">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="user_id" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="task_id" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="date_time" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="task_id_votes">
+ <col>task_id</col>
+ </index>
+ </table>
+ <table name="links">
+ <descr>link a resource (e.g. an URL) with a task - in a more structured way than the task description text area.</descr>
+ <field name="link_id" type="I" size="11">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="task_id" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="comment_id" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="url" type="X">
+ <NOTNULL/>
+ </field>
+ <field name="added_by" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="date_added" type="I" size="11">
+ <NONULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="task_id_links">
+ <col>task_id</col>
+ </index>
+ </table>
+ <sql>
+ <query>INSERT INTO groups VALUES (DEFAULT, 'Admin', 'Members have unlimited access to all functionality', 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1);</query>
+ <query>INSERT INTO groups VALUES (DEFAULT, 'Developers', 'Global Developers for all projects', 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1);</query>
+ <query>INSERT INTO groups VALUES (DEFAULT, 'Reporters', 'Open new tasks / add comments in all projects', 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1);</query>
+ <query>INSERT INTO groups VALUES (DEFAULT, 'Basic', 'Members can login, relying upon Project permissions only', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1);</query>
+ <query>INSERT INTO groups VALUES (DEFAULT, 'Pending', 'Users who are awaiting approval of their accounts', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);</query>
+ <query>INSERT INTO groups VALUES (DEFAULT, 'Project Managers', 'Permission to do anything related to the Default Project', 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1);</query>
+ <query>INSERT INTO history VALUES (DEFAULT, 1, 1, 1130024797, 1, '', '', '');</query>
+ <query>INSERT INTO list_category VALUES (DEFAULT, 1, 'Backend / Core', 1, 0, 2, 3);</query>
+ <query>INSERT INTO list_category VALUES (DEFAULT, 0, 'root', 0, 0, 1, 2);</query>
+ <query>INSERT INTO list_category VALUES (DEFAULT, 1, 'root', 0, 0, 1, 4);</query>
+ <query>INSERT INTO list_os VALUES (DEFAULT, 1, 'All', 1, 1);</query>
+ <query>INSERT INTO list_os VALUES (DEFAULT, 1, 'Windows', 2, 1);</query>
+ <query>INSERT INTO list_os VALUES (DEFAULT, 1, 'Linux', 3, 1);</query>
+ <query>INSERT INTO list_os VALUES (DEFAULT, 1, 'Mac OS', 4, 1);</query>
+ <query>INSERT INTO list_resolution VALUES (DEFAULT, 'Not a bug', 1, 1, 0);</query>
+ <query>INSERT INTO list_resolution VALUES (DEFAULT, 'Won''t fix', 2, 1, 0);</query>
+ <query>INSERT INTO list_resolution VALUES (DEFAULT, 'Won''t implement', 3, 1, 0);</query>
+ <query>INSERT INTO list_resolution VALUES (DEFAULT, 'Works for me', 4, 1, 0);</query>
+ <query>INSERT INTO list_resolution VALUES (DEFAULT, 'Deferred', 5, 1, 0);</query>
+ <query>INSERT INTO list_resolution VALUES (DEFAULT, 'Duplicate', 6, 1, 0);</query>
+ <query>INSERT INTO list_resolution VALUES (DEFAULT, 'Fixed', 7, 1, 0);</query>
+ <query>INSERT INTO list_resolution VALUES (DEFAULT, 'Implemented', 8, 1, 0);</query>
+ <query>INSERT INTO list_tasktype VALUES (DEFAULT, 'Bug Report', 1, 1, 0);</query>
+ <query>INSERT INTO list_tasktype VALUES (DEFAULT, 'Feature Request', 2, 1, 0);</query>
+ <query>INSERT INTO list_version VALUES (DEFAULT, 1, 'Development', 1, 1, 2);</query>
+ <query>INSERT INTO list_status (status_name, list_position, show_in_list, project_id) VALUES ('Unconfirmed', 1, 1, 0)</query>
+ <query>INSERT INTO list_status (status_name, list_position, show_in_list, project_id) VALUES ('New', 2, 1, 0)</query>
+ <query>INSERT INTO list_status (status_name, list_position, show_in_list, project_id) VALUES ('Assigned', 3, 1, 0)</query>
+ <query>INSERT INTO list_status (status_name, list_position, show_in_list, project_id) VALUES ('Researching', 4, 1, 0)</query>
+ <query>INSERT INTO list_status (status_name, list_position, show_in_list, project_id) VALUES ('Waiting on Customer', 5, 1, 0)</query>
+ <query>INSERT INTO list_status (status_name, list_position, show_in_list, project_id) VALUES ('Requires testing', 6, 1, 0)</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'fs_ver', '1.0');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'logo', 'flyspray_small.png');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'gravatars', '0');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'emailNoHTML', '0');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'jabber_server', '');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'jabber_port', '5222');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'jabber_username', '');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'jabber_password', '');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'anon_group', '4');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'user_notify', '1');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'admin_email', 'flyspray@example.com');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'lang_code', 'en');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'need_approval', '0');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'spam_proof', '1');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'default_project', '1');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'default_entry', 'index');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'dateformat', '');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'dateformat_extended', '');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'anon_reg', '1');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'global_theme', 'CleanFS');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'visible_columns', 'id category tasktype priority severity summary status progress');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'visible_fields', 'tasktype category severity priority status private assignedto reportedin dueversion duedate progress os votes');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'smtp_server', '');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'smtp_user', '');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'smtp_pass', '');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'page_title', 'Flyspray::');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'notify_registration', '0');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'jabber_ssl', '0');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'last_update_check', '0');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'intro_message', '');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'cache_feeds', '1');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'disable_lostpw', '0');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'disable_changepw', '0');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'days_before_alert', '0');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'hide_emails', '1');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'pages_welcome_msg', 'index');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'active_oauths', '');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'only_oauth_reg', '0');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'enable_avatars', '1');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'max_avatar_size', '50');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'default_order_by', 'id');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'default_order_by_dir', 'desc');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'url_rewriting', '0');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'max_vote_per_day', '2');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'votes_per_project', '10');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'custom_style', '');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'general_integration', '');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'footer_integration', '');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'repeat_password', '0');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'repeat_emailaddress', '0');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'massops', '0');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'captcha_securimage', '0');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'captcha_recaptcha', '0');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'captcha_recaptcha_sitekey', '');</query>
+ <query>INSERT INTO prefs VALUES (DEFAULT, 'captcha_recaptcha_secret', '');</query>
+ <query>INSERT INTO projects VALUES (DEFAULT, 'Default Project', 'CleanFS', 0, 'Welcome to your first Flyspray project! We hope that Flyspray provides you with many hours of increased productivity. If you have any issues, go to http://flyspray.org . You can customise this message [[?do=pm&amp;project=1|here]]', 1, 'id category tasktype priority severity summary status progress', 'tasktype category severity priority status private assignedto reportedin dueversion duedate progress os votes', 1, 1, 0, '', '', NULL, '0', NULL, NULL, '', 'en', 0, 0, 0, NULL, 'index', 0, 0,'Undecided', '', 0, 0, 0, 'id desc', 'DESC', '', 1 );</query>
+ <query>INSERT INTO tasks VALUES (DEFAULT, 1, 1, 1452600000, 1, 0, 0, 0, ' ', 'Sample Task', 'This isn''t a real task. You should close it and start opening some real tasks.', 2, 1, 1, 1, 0, 1, 1, 2, 0, 0, 0, 0, 0, '', '0', 0, 0, 0);</query>
+ <query>INSERT INTO users VALUES (DEFAULT, 'super', '1b3231655cebb7a1f783eddf27d254ca', 'Superuser', '', '', 0, 1, 1, '', '', '', 25, 0, 0, 0, 0, 'en', '0', '', '', 0, 0, NULL);</query>
+ <query>INSERT INTO users_in_groups VALUES (DEFAULT, 1, 1);</query>
+ </sql>
+</schema>
diff --git a/setup/upgrade/1.0/upgrade.info b/setup/upgrade/1.0/upgrade.info
new file mode 100644
index 0000000..a1510a5
--- /dev/null
+++ b/setup/upgrade/1.0/upgrade.info
@@ -0,0 +1,70 @@
+[defaultupgrade]
+1="upgrade.xml"
+2="varchartotext.php"
+
+[develupgrade]
+1="upgrade.xml"
+2="varchartotext.php"
+
+[fsprefs]
+fs_ver="1.0"
+logo="flyspray_small.png"
+jabber_server=""
+jabber_port="5222"
+jabber_username=""
+jabber_password=""
+anon_group="0"
+user_notify="1"
+admin_email="flyspray@example.com"
+lang_code="en"
+need_approval="0"
+spam_proof="1"
+default_project="1"
+default_entry="index"
+dateformat=""
+dateformat_extended=""
+anon_reg="1"
+page_title="Flyspray:: "
+notify_registration="0"
+jabber_ssl="0"
+last_update_check="0"
+cache_feeds="1"
+global_theme="CleanFS"
+visible_columns="id supertask project tasktype severity summary status progress"
+visible_fields="supertask tasktype category severity priority status private assignedto reportedin dueversion duedate progress os votes"
+smtp_server=""
+smtp_user=""
+smtp_pass=""
+lock_for="5"
+email_ssl="0"
+email_tls="0"
+gravatars="0"
+emailNoHTML="0"
+default_timezone="0"
+intro_message=""
+disable_lostpw="0"
+disable_changepw="0"
+days_before_alert="0"
+hide_emails="1"
+pages_welcome_msg="index"
+active_oauths=""
+only_oauth_reg="0"
+enable_avatars="1"
+max_avatar_size="50"
+default_order_by="id"
+default_order_by_dir="desc"
+url_rewriting="0"
+max_vote_per_day="2"
+votes_per_project="10"
+custom_style=""
+general_integration=""
+footer_integration=""
+repeat_password="0"
+repeat_emailaddress="0"
+massops="0"
+; Would like to see captchastuff be optional prefs, but
+; current upgrade logic wipes such additional prefs if not listed here too.
+captcha_securimage="0"
+captcha_recaptcha="0"
+captcha_recaptcha_sitekey=""
+captcha_recaptcha_secret=""
diff --git a/setup/upgrade/1.0/upgrade.xml b/setup/upgrade/1.0/upgrade.xml
new file mode 100644
index 0000000..0a48596
--- /dev/null
+++ b/setup/upgrade/1.0/upgrade.xml
@@ -0,0 +1,902 @@
+<?xml version="1.0"?>
+<schema version="0.3">
+ <table name="attachments">
+ <descr>List the names and locations of files attached to tasks</descr>
+ <field name="attachment_id" type="I" size="5">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="task_id" type="I" size="10">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="comment_id" type="I" size="10">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="orig_name" type="C" size="255">
+ <NOTNULL/>
+ </field>
+ <field name="file_name" type="C" size="30">
+ <NOTNULL/>
+ </field>
+ <field name="file_type" type="C" size="255">
+ <NOTNULL/>
+ </field>
+ <field name="file_size" type="I" size="20">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="added_by" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="date_added" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="task_id_attachments">
+ <col>task_id</col>
+ <col>comment_id</col>
+ </index>
+ </table>
+ <table name="cache">
+ <field name="id" type="I" size="6">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="type" type="C" size="4">
+ <NOTNULL/>
+ </field>
+ <field name="content" type="XL">
+ <NOTNULL/>
+ </field>
+ <field name="topic" type="I" size="11">
+ <NOTNULL/>
+ </field>
+ <field name="last_updated" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="project_id" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="max_items" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="cache_type">
+ <UNIQUE/>
+ <col>type</col>
+ <col>topic</col>
+ <col>project_id</col>
+ <col>max_items</col>
+ </index>
+ <index name="cache_type_topic">
+ <col>type</col>
+ <col>topic</col>
+ </index>
+ </table>
+ <table name="users">
+ <field name="user_id" type="I" size="3">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="user_name" type="C" size="32">
+ <NOTNULL/>
+ </field>
+ <field name="user_pass" type="C" size="128"/>
+ <field name="real_name" type="C" size="100">
+ <NOTNULL/>
+ </field>
+ <field name="jabber_id" type="C" size="100">
+ <NOTNULL/>
+ </field>
+ <field name="email_address" type="C" size="100">
+ <NOTNULL/>
+ </field>
+ <field name="notify_type" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="notify_own" type="I" size="6">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="account_enabled" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="dateformat" type="C" size="30">
+ <NOTNULL/>
+ <DEFAULT value=""/>
+ </field>
+ <field name="dateformat_extended" type="C" size="30">
+ <NOTNULL/>
+ <DEFAULT value=""/>
+ </field>
+ <field name="magic_url" type="C" size="40">
+ <NOTNULL/>
+ <DEFAULT value=""/>
+ </field>
+ <field name="tasks_perpage" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="register_date" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="time_zone" type="I" size="6">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="login_attempts" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="lock_until" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="lang_code" type="C" size="10">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="oauth_uid" type="C" size="255">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="oauth_provider" type="C" size="10">
+ <NOTNULL/>
+ <DEFAULT value=""/>
+ </field>
+ <field name="profile_image" type="C" size="100">
+ <NOTNULL/>
+ <DEFAULT value=""/>
+ </field>
+ <field name="hide_my_email" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="notify_online" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="last_login" type="I" size="11">
+ <descr>last login of a user</descr>
+ <NULL/>
+ </field>
+ <index name="user_name">
+ <UNIQUE/>
+ <col>user_name</col>
+ </index>
+ </table>
+ <table name="user_emails">
+ <field name="id" type="I" size="5"></field>
+ <field name="email_address" type="C" size="100"></field>
+ <field name="oauth_uid" type="C" size="255">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="oauth_provider" type="C" size="10">
+ <NOTNULL/>
+ <DEFAULT value=""/>
+ </field>
+ </table>
+ <table name="effort">
+ <field name="effort_id" type="I" size="10">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="task_id" type="I" size="10">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="date_added" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="user_id" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="start_timestamp" type="I" size="11"/>
+ <field name="end_timestamp" type="I" size="11"/>
+ <field name="effort" type="I" size="15">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="task_id_effort">
+ <col>task_id</col>
+ </index>
+ </table>
+ <table name="groups">
+ <field name="group_id" type="I" size="3">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="group_name" type="C" size="20">
+ <NOTNULL/>
+ </field>
+ <field name="group_desc" type="C" size="150">
+ <NOTNULL/>
+ </field>
+ <field name="project_id" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="is_admin" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="manage_project" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="view_tasks" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="open_new_tasks" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="modify_own_tasks" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="modify_all_tasks" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="view_comments" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="add_comments" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="edit_comments" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="edit_own_comments" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="delete_comments" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="create_attachments" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="delete_attachments" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="view_history" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="close_own_tasks" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="close_other_tasks" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="assign_to_self" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="assign_others_to_self" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="add_to_assignees" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="view_reports" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="add_votes" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="edit_assignments" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="show_as_assignees" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="view_estimated_effort" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="view_current_effort_done" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="track_effort" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="group_open" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="add_multiple_tasks" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="view_roadmap" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="view_own_tasks" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="view_groups_tasks" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="group_name">
+ <UNIQUE/>
+ <col>group_name</col>
+ <col>project_id</col>
+ </index>
+ <index name="belongs_to_project">
+ <col>project_id</col>
+ </index>
+ </table>
+ <table name="prefs">
+ <descr>global settings of Flyspray</descr>
+ <field name="pref_id" type="I" size="1">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="pref_name" type="C" size="40">
+ <NOTNULL/>
+ </field>
+ <field name="pref_value" type="X" />
+ </table>
+ <table name="projects">
+ <field name="project_id" type="I" size="3">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="project_title" type="C" size="100">
+ <NOTNULL/>
+ </field>
+ <field name="theme_style" type="C" size="20">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="default_cat_owner" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="intro_message" type="X">
+ <NOTNULL/>
+ <DEFAULT value=""/>
+ </field>
+ <field name="project_is_active" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="visible_columns" type="C" size="255">
+ <NOTNULL/>
+ </field>
+ <field name="visible_fields" type="C" size="255">
+ <NOTNULL/>
+ <DEFAULT value=""/>
+ </field>
+ <field name="others_view" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="others_viewroadmap" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="anon_open" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="notify_email" type="X">
+ <NOTNULL/>
+ <DEFAULT value=""/>
+ </field>
+ <field name="notify_jabber" type="X">
+ <NOTNULL/>
+ <DEFAULT value=""/>
+ </field>
+ <field name="notify_reply" type="X">
+ <NOTNULL/>
+ <DEFAULT value=""/>
+ </field>
+ <field name="notify_types" type="C" size="100">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="feed_img_url" type="X">
+ <NOTNULL/>
+ <DEFAULT value=""/>
+ </field>
+ <field name="feed_description" type="X">
+ <NOTNULL/>
+ <DEFAULT value=""/>
+ </field>
+ <field name="notify_subject" type="C" size="100">
+ <NOTNULL/>
+ <DEFAULT value=""/>
+ </field>
+ <field name="lang_code" type="C" size="10">
+ <NOTNULL/>
+ </field>
+ <field name="comment_closed" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="auto_assign" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="last_updated" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="default_task" type="X">
+ <NOTNULL/>
+ </field>
+ <field name="default_entry" type="C" size="8">
+ <NOTNULL/>
+ <DEFAULT value="index"/>
+ </field>
+ <field name="disp_intro" type="I" size="1">
+ <DEFAULT value="0"/>
+ </field>
+ <field name="use_effort_tracking" type="I" size="1">
+ <DEFAULT value="0"/>
+ </field>
+ <field name="default_due_version" type="C" size="40">
+ <NOTNULL/>
+ <DEFAULT value="Undecided"/>
+ </field>
+ <field name="pages_intro_msg" type="C" size="80">
+ <NOTNULL/>
+ <DEFAULT value="index"/>
+ </field>
+ <field name="hours_per_manday" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="estimated_effort_format" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="current_effort_done_format" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="default_order_by" type="C" size="100">
+ <NOTNULL/>
+ <DEFAULT value="id"/>
+ </field>
+ <field name="default_order_by_dir" type="C" size="5">
+ <NOTNULL/>
+ <DEFAULT value="desc"/>
+ </field>
+ <field name="custom_style" type="C" size="32">
+ </field>
+ <field name="freetagging" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ </table>
+ <table name="tasks">
+ <field name="task_id" type="I" size="10">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="project_id" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="task_type" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="date_opened" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="opened_by" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="is_closed" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="date_closed" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="closed_by" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="closure_comment" type="X">
+ <NOTNULL/>
+ </field>
+ <field name="item_summary" type="C" size="100">
+ <NOTNULL/>
+ </field>
+ <field name="detailed_desc" type="X">
+ <NOTNULL/>
+ </field>
+ <field name="item_status" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="resolution_reason" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="1"/>
+ </field>
+ <field name="product_category" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="product_version" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="closedby_version" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="operating_system" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="task_severity" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="task_priority" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="last_edited_by" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="last_edited_time" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="percent_complete" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="mark_private" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="due_date" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="anon_email" type="C" size="100">
+ <NOTNULL/>
+ <DEFAULT value=""/>
+ </field>
+ <field name="task_token" type="C" size="32">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="supertask_id" type="I" size="10">
+ <DEFAULT value="0"/>
+ </field>
+ <field name="list_order" type="I" size="3">
+ <DEFAULT value="0"/>
+ </field>
+ <field name="estimated_effort" type="I" size="3">
+ <DEFAULT value="0"/>
+ </field>
+ <index name="attached_to_project">
+ <col>project_id</col>
+ </index>
+ <index name="task_severity">
+ <col>task_severity</col>
+ </index>
+ <index name="task_type">
+ <col>task_type</col>
+ </index>
+ <index name="product_category">
+ <col>product_category</col>
+ </index>
+ <index name="item_status">
+ <col>item_status</col>
+ </index>
+ <index name="is_closed">
+ <col>is_closed</col>
+ </index>
+ <index name="closedby_version">
+ <col>closedby_version</col>
+ </index>
+ <index name="due_date">
+ <col>due_date</col>
+ </index>
+ <index name="task_project_super">
+ <col>project_id</col>
+ <col>supertask_id</col>
+ <col>list_order</col>
+ </index>
+ <index name="task_super">
+ <col>supertask_id</col>
+ <col>list_order</col>
+ </index>
+ </table>
+ <table name="links">
+ <field name="link_id" type="I" size="11">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="task_id" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="comment_id" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="url" type="X">
+ <NOTNULL/>
+ </field>
+ <field name="added_by" type="I" size="11">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="date_added" type="I" size="11">
+ <NONULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="task_id_links">
+ <col>task_id</col>
+ </index>
+ </table>
+ <table name="tags">
+ <field name="task_id" type="I" size="5"></field>
+ <field name="tag" type="C" size="100"></field>
+ </table>
+ <table name="list_category">
+ <field name="category_id" type="I" size="3">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="project_id" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="category_name" type="C" size="40">
+ <NOTNULL/>
+ </field>
+ <field name="show_in_list" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="category_owner" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="lft" type="I" size="10">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ <UNSIGNED/>
+ </field>
+ <field name="rgt" type="I" size="10">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ <UNSIGNED/>
+ </field>
+ <index name="project_id_cat">
+ <col>project_id</col>
+ </index>
+ </table>
+ <table name="list_os">
+ <field name="os_id" type="I" size="3">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="project_id" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="os_name" type="C" size="40">
+ <NOTNULL/>
+ </field>
+ <field name="list_position" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="show_in_list" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="project_id_os">
+ <UNIQUE/>
+ <col>project_id</col>
+ <col>os_name</col>
+ </index>
+ </table>
+ <table name="list_resolution">
+ <field name="resolution_id" type="I" size="3">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="resolution_name" type="C" size="40">
+ <NOTNULL/>
+ </field>
+ <field name="list_position" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="show_in_list" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="project_id" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="project_id_res">
+ <UNIQUE/>
+ <col>project_id</col>
+ <col>resolution_name</col>
+ </index>
+ </table>
+ <table name="list_status">
+ <field name="status_id" type="I" size="3">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="status_name" type="C" size="40">
+ <NOTNULL/>
+ </field>
+ <field name="list_position" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="show_in_list" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="project_id" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="project_id_status">
+ <UNIQUE/>
+ <col>project_id</col>
+ <col>status_name</col>
+ </index>
+ </table>
+ <table name="list_tag">
+ <field name="tag_id" type="I" size="5">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="project_id" type="I" size="5">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="tag_name" type="C" size="40">
+ <NOTNULL/>
+ </field>
+ <field name="list_position" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="show_in_list" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="class" type="C" size="100"/>
+ <index name="project_id_tag">
+ <UNIQUE/>
+ <col>project_id</col>
+ <col>tag_name</col>
+ </index>
+ </table>
+ <table name="list_tasktype">
+ <field name="tasktype_id" type="I" size="3">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="tasktype_name" type="C" size="40">
+ <NOTNULL/>
+ </field>
+ <field name="list_position" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="show_in_list" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="project_id" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="project_id_tt">
+ <UNIQUE/>
+ <col>project_id</col>
+ <col>tasktype_name</col>
+ </index>
+ </table>
+ <table name="list_version">
+ <field name="version_id" type="I" size="3">
+ <KEY/>
+ <AUTOINCREMENT/>
+ </field>
+ <field name="project_id" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="version_name" type="C" size="40">
+ <NOTNULL/>
+ </field>
+ <field name="list_position" type="I" size="3">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="show_in_list" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <field name="version_tense" type="I" size="1">
+ <NOTNULL/>
+ <DEFAULT value="0"/>
+ </field>
+ <index name="project_id_version_name">
+ <UNIQUE/>
+ <col>project_id</col>
+ <col>version_name</col>
+ </index>
+ <index name="project_id_version">
+ <col>project_id</col>
+ <col>version_tense</col>
+ </index>
+ </table>
+ <table name="task_tag">
+ <field name="task_id" type="I" size="5">
+ <KEY/>
+ </field>
+ <field name="tag_id" type="I" size="5">
+ <KEY/>
+ </field>
+ <index name="task_id_tag">
+ <UNIQUE/>
+ <col>task_id</col>
+ <col>tag_id</col>
+ </index>
+ </table>
+ <sql>
+ <query>UPDATE projects SET visible_fields = 'tasktype category severity priority status private assignedto reportedin dueversion duedate progress os votes' WHERE visible_fields = ''</query>
+ <query>UPDATE projects SET theme_style = 'CleanFS'</query>
+ <query>UPDATE prefs SET pref_value = 'CleanFS' WHERE pref_name = 'global_theme'</query>
+ </sql>
+</schema>
diff --git a/setup/upgrade/1.0/varchartotext.php b/setup/upgrade/1.0/varchartotext.php
new file mode 100644
index 0000000..3bba5ea
--- /dev/null
+++ b/setup/upgrade/1.0/varchartotext.php
@@ -0,0 +1,17 @@
+<?php
+if ($conf['database']['dbtype'] == 'pgsql') {
+ $db->query('ALTER TABLE {prefs} ALTER COLUMN pref_value TYPE text');
+ $db->query('ALTER TABLE {prefs} ALTER COLUMN pref_value SET DEFAULT \'\'');
+}
+elseif($db->dbtype=='mysqli' || $db->dbtype=='mysql') {
+ $sinfo=$db->dblink->serverInfo();
+ if(isset($sinfo['version']) && version_compare($sinfo['version'], '5.5.3')>=0 ){
+ $db->query('ALTER TABLE {prefs} CHANGE `pref_value` `pref_value` TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL');
+ }else{
+ $db->query('ALTER TABLE {prefs} CHANGE `pref_value` `pref_value` TEXT CHARACTER SET utf8 COLLATE utf8_bin NOT NULL');
+ }
+}
+else{
+ $db->query('ALTER TABLE {prefs} CHANGE `pref_value` `pref_value` TEXT CHARACTER SET utf8 COLLATE utf8_bin NOT NULL');
+}
+?>