[nag] [patch] Make nag use category driver

Jason M. Felice jfelice at cronosys.com
Wed Aug 27 11:04:12 PDT 2003


Includes script to convert existing tasks.  There are some file additions
and deletions in the patch to beware of when cvs committing.  Changes to
documentation also.

-- 
 Jason M. Felice
 Cronosys, LLC <http://www.cronosys.com/>
 216.221.4600 x302
-------------- next part --------------
epm diff lib/Driver/sql.php
--- lib/Driver/sql.php	2003-08-27 09:29:49.000000000 -0400
+++ lib/Driver/sql.php	1969-12-31 19:00:00.000000000 -0500
@@ -1,312 +0,0 @@
-<?php
-/**
- * Nag storage implementation for PHP's PEAR database abstraction layer.
- *
- * Required values for $params:<pre>
- *      'phptype'       The database type (e.g. 'pgsql', 'mysql', etc.).
- *      'hostspec'      The hostname of the database server.
- *      'protocol'      The communication protocol ('tcp', 'unix', etc.).
- *      'username'      The username with which to connect to the database.
- *      'password'      The password associated with 'username'.
- *      'database'      The name of the database.
- *      'table'         The name of the tasks table in 'database'.</pre>
- *      'charset'       The database's internal charset.
- *
- * Required by some database implementations:
- *      'options'       Additional options to pass to the database.
- *      'tty'           The TTY on which to connect to the database.
- *      'port'          The port on which to connect to the database.
- *
- * The table structure can be created by the scripts/drivers/nag_tasks.sql
- * script.
- *
- * $Horde: nag/lib/Driver/sql.php,v 1.41 2003/08/23 20:06:04 jan Exp $
- *
- * @author  Jon Parise <jon at horde.org>
- * @version $Revision: 1.41 $
- * @since   Nag 0.1
- * @package nag
- */
-class Nag_Driver_sql extends Nag_Driver {
-
-    /** Hash containing connection parameters. */
-    var $_params = array();
-
-    /** Handle for the current database connection.
-        @var object DB $db */
-    var $_db;
-
-    /** Boolean indicating whether or not we're connected to the SQL server. */
-    var $_connected = false;
-
-    /**
-     * Constructs a new SQL storage object.
-     *
-     * @param string $user      The user who owns these tasks.
-     * @param array  $params    A hash containing connection parameters.
-     */
-    function Nag_Driver_sql($user, $params = array())
-    {
-        $this->_user = $user;
-        $this->_params = $params;
-    }
-
-    /**
-     * Disconnect from the SQL server and clean up the connection.
-     *
-     * @return boolean     true on success, false on failure.
-     */
-    function _disconnect()
-    {
-        if ($this->_connected) {
-            $this->_connected = false;
-            return $this->_db->disconnect();
-        }
-
-        return true;
-    }
-
-    /**
-     * Retrieves the user's tasks from the database.
-     *
-     * @return mixed  True on success, PEAR_Error on failure.
-     */
-    function retrieve()
-    {
-        /* Make sure we have a valid database connection. */
-        $this->_connect();
-
-        /* Build the SQL query. */
-        $query = sprintf('SELECT * FROM %s WHERE task_owner = %s',
-                         $this->_params['table'], $this->_db->quote($this->_user));
-
-        /* Log the query at a DEBUG log level. */
-        Horde::logMessage(sprintf('Nag_Driver_sql::retrieve(): %s', $query),
-                          __FILE__, __LINE__, PEAR_LOG_DEBUG);
-
-        /* Execute the query. */
-        $result = $this->_db->query($query);
-
-        if (isset($result) && !is_a($result, 'PEAR_Error')) {
-            $row = $result->fetchRow(DB_FETCHMODE_ASSOC);
-            if (is_a($row, 'PEAR_Error')) {
-                return $row;
-            }
-
-            /* Store the retrieved values in a fresh $tasks list. */
-            $this->_tasks = array();
-            while ($row && !is_a($row, 'PEAR_Error')) {
-                /* Add this new task to the $tasks list. */
-                $this->_tasks[$row['task_id']] = $this->_buildTask($row);
-
-                /* Advance to the new row in the result set. */
-                $row = $result->fetchRow(DB_FETCHMODE_ASSOC);
-            }
-            $result->free();
-        } else {
-            return $result;
-        }
-
-        return true;
-    }
-
-    /**
-     * Stores the user's tasks to SQL server.
-     *
-     * @return mixed  True on success, PEAR_Error on failure.
-     */
-    function store()
-    {
-        /* Build lists of the tasks that require pending database operations. */
-        $added_tasks = $this->listTasks(TASK_ADDED);
-        $modified_tasks = $this->listTasks(TASK_MODIFIED);
-        $deleted_tasks = $this->listTasks(TASK_DELETED);
-
-        /* If there are no pending operations, exit successfully now. */
-        if ((count($added_tasks) == 0) && (count($modified_tasks) == 0) &&
-            (count($deleted_tasks) == 0)) {
-            return true;
-        }
-
-        /* Make sure we have a valid database connection. */
-        $this->_connect();
-
-        /* Perform any pending additions. */
-        if (count($added_tasks) > 0) {
-            foreach ($added_tasks as $task_id => $task) {
-                $query = sprintf(
-                    'INSERT INTO %s (task_owner, task_id, task_name, ' .
-                    'task_desc, task_due, task_priority, ' .
-                    'task_completed, task_category, task_modified, '.
-                    'task_alarm) ' .
-                    'VALUES (%s, %d, %s, %s, %d, %d, %d, %d, %d, %d)',
-                    $this->_params['table'],
-                    $this->_db->quote($this->_user),
-                    $task_id,
-                    String::convertCharset($this->_db->quote($task['name']), NLS::getCharset(), $this->_params['charset']),
-                    String::convertCharset($this->_db->quote($task['desc']), NLS::getCharset(), $this->_params['charset']),
-                    $task['due'],
-                    $task['priority'],
-                    $task['completed'],
-                    $task['category'],
-                    time(),
-                    $task['alarm']);
-
-                    /* Log the query at a DEBUG log level. */
-                    Horde::logMessage(sprintf('Nag_Driver_sql::store(): %s', $query),
-                                      __FILE__, __LINE__, PEAR_LOG_DEBUG);
-
-                /* Attempt the insertion query. */
-                $result = $this->_db->query($query);
-
-                /* Return an error immediately if the query failed. */
-                if (is_a($result, 'PEAR_Error')) {
-                    Horde::logMessage($result, __FILE__, __LINE__, PEAR_LOG_ERR);
-                    return $result;
-                }
-
-                /* Remove the "added" flag from this task. */
-                $this->setFlag($task_id, TASK_ADDED, false);
-            }
-        }
-
-        /* Perform any pending modifications. */
-        if (count($modified_tasks) > 0) {
-            foreach ($modified_tasks as $task_id => $task) {
-                $query  = sprintf('UPDATE %s SET ', $this->_params['table']);
-                $query .= sprintf('task_name = %s, ',
-                                  String::convertCharset($this->_db->quote($task['name']), NLS::getCharset(), $this->_params['charset']));
-                $query .= sprintf('task_desc = %s, ',
-                                  String::convertCharset($this->_db->quote($task['desc']), NLS::getCharset(), $this->_params['charset']));
-                $query .= sprintf('task_due = %d, ', $task['due']);
-                $query .= sprintf('task_priority = %d, ', $task['priority']);
-                $query .= sprintf('task_completed = %d, ', $task['completed']);
-                $query .= sprintf('task_category = %d, ', $task['category']);
-                $query .= sprintf('task_modified = %d, ', time());
-                $query .= sprintf('task_alarm = %d ', $task['alarm']);
-                $query .= sprintf('WHERE task_owner = %s AND task_id = %d',
-                                  $this->_db->quote($this->_user), $task_id);
-
-                /* Log the query at a DEBUG log level. */
-                Horde::logMessage(sprintf('Nag_Driver_sql::store(): %s', $query),
-                                  __FILE__, __LINE__, PEAR_LOG_DEBUG);
-
-                /* Attempt the update query. */
-                $result = $this->_db->query($query);
-
-                /* Return an error immediately if the query failed. */
-                if (is_a($result, 'PEAR_Error')) {
-                    return $result;
-                }
-
-                /* Remove the "modified" flag from this task. */
-                $this->setFlag($task_id, TASK_MODIFIED, false);
-            }
-        }
-
-        /* Perform any pending deletions. */
-        if (count($deleted_tasks) > 0) {
-            $task_ids = array_keys($deleted_tasks);
-            $where = 'task_id = ' . $task_ids[0];
-            if (count($task_ids) > 1) {
-                array_shift($task_ids);
-                $where .= ' OR task_id = ' . implode(' OR task_id =', $task_ids);
-            }
-
-            $query = sprintf('DELETE FROM %s WHERE task_owner = %s AND (%s)',
-                             $this->_params['table'],
-                             $this->_db->quote($this->_user),
-                             $where);
-
-            /* Log the query at a DEBUG log level. */
-            Horde::logMessage(sprintf('Nag_Driver_sql::store(): %s', $query),
-                              __FILE__, __LINE__, PEAR_LOG_DEBUG);
-
-            /* Attempt the delete query. */
-            $result = $this->_db->query($query);
-
-            /* Return an error immediately if the query failed. */
-            if (is_a($result, 'PEAR_Error')) {
-                return $result;
-            }
-
-            /* Purge the deleted tasks. */
-            $this->purgeDeleted();
-        }
-
-        return true;
-    }
-
-    function listAlarms($date)
-    {
-        $q  = 'SELECT * FROM ' . $this->_params['table'];
-        $q .= ' WHERE task_owner = ' . $this->_db->quote($this->_user);
-        $q .= ' AND task_alarm > 0';
-        $q .= ' AND (task_due - (task_alarm * 60) <= ' . $this->_db->quote($date) . ')';
-        $q .= ' AND task_due >= ' . $this->_db->quote(time());
-
-        /* Log the query at a DEBUG log level. */
-        Horde::logMessage(sprintf('SQL alarms list by %s: table = %s; query = "%s"',
-                                  Auth::getAuth(), $this->_params['table'], $q),
-                          __FILE__, __LINE__, PEAR_LOG_DEBUG);
-
-        /* Run the query. */
-        $qr = $this->_db->getAll($q, DB_FETCHMODE_ASSOC);
-        if (is_a($qr, 'PEAR_Error')) {
-            return $qr;
-        }
-
-        $tasks = array();
-        foreach ($qr as $row) {
-            $tasks[$row['task_id']] = $this->_buildTask($row);
-        }
-        return $tasks;
-    }
-
-    function _buildTask($row)
-    {
-        /* Create a new task based on $row's values. */
-        $task = array();
-        $task['task_id'] = $row['task_id'];
-        $task['tasklist_id'] = $this->_user;
-        $task['name'] = String::convertCharset($row['task_name'], $this->_params['charset']);
-        $task['desc'] = String::convertCharset($row['task_desc'], $this->_params['charset']);
-        $task['category'] = $row['task_category'];
-        $task['due'] = $row['task_due'];
-        $task['priority'] = $row['task_priority'];
-        $task['completed'] = $row['task_completed'];
-        $task['alarm'] = $row['task_alarm'];
-        $task['flags'] = 0;
-
-        return $task;
-    }
-
-    /**
-     * Attempts to open a persistent connection to the SQL server.
-     *
-     * @return boolean    True on success; exits (Horde::fatal()) on error.
-     */
-    function _connect()
-    {
-        if (!$this->_connected) {
-            Horde::assertDriverConfig($this->_params, 'storage',
-                array('phptype', 'hostspec', 'username', 'database', 'charset', 'table'));
-
-            /* Connect to the SQL server using the supplied parameters. */
-            require_once 'DB.php';
-            $this->_db = &DB::connect($this->_params,
-                                      array('persistent' => !empty($this->_params['persistent'])));
-            if (is_a($this->_db, 'PEAR_Error')) {
-                Horde::fatal($this->_db, __FILE__, __LINE__);
-            }
-
-            /* Enable the "portability" option. */
-            $this->_db->setOption('optimize', 'portability');
-
-            $this->_connected = true;
-        }
-
-        return true;
-    }
-
-}
epm diff lib/Driver.php
--- lib/Driver.php	Wed Aug 27 09:29:53 2003
+++ lib/Driver.php	Wed Aug 27 13:30:44 2003
@@ -40,37 +40,42 @@
     var $_user = '';
 
     /**
-     * Attempts to return a concrete Nag_Driver instance based on $driver.
-     *
-     * @param string    $driver     The type of concrete Nag_Driver subclass
-     *                              to return.  The is based on the storage
-     *                              driver ($driver).  The code is dynamically
-     *                              included.
+     * Reference to the category instance.
+     * @var object $tasks_category
+     */
+    var $_tasks_category = null;
+
+    /**
+     * Constructs a new driver.
      *
      * @param string    $user       The name of the user who owns these tasks.
      *
-     * @param array     $params     (optional) A hash containing any additional
-     *                              configuration or connection parameters a
-     *                              subclass might need.
+     * @return object Nag_Driver    The driver reference.
+     */
+    function Nag_Driver($user)
+    {
+        global $conf;
+
+        $this->_user = $user;
+
+        $driver = $conf['category']['driver'];
+        $params = Horde::getDriverConfig('category', $driver);
+        $params = array_merge($params, array( 'group' => 'nag.tasks' ));
+
+        $this->_tasks_category = &Category::singleton($driver, $params);
+    }
+
+    /**
+     * Attempts to return a concrete Nag_Driver instance based on $driver.
+     *
+     * @param string    $user       The name of the user who owns these tasks.
      *
      * @return mixed    The newly created concrete Nag_Driver instance, or
      *                  false on an error.
      */
-    function &factory($driver, $user, $params = null)
+    function &factory($user)
     {
-        $driver = basename($driver);
-
-        if (is_null($params)) {
-            $params = Horde::getDriverConfig('storage', $driver);
-        }
-
-        require_once dirname(__FILE__) . '/Driver/' . $driver . '.php';
-        $class = 'Nag_Driver_' . $driver;
-        if (class_exists($class)) {
-            return new $class($user, $params);
-        } else {
-            return false;
-        }
+	return new Nag_Driver($user);
     }
 
     /**
@@ -83,38 +88,20 @@
      *
      * This method must be invoked as: $var = &Nag_Driver::singleton()
      *
-     * @param string    $driver     The type of concrete Nag_Driver subclass
-     *                              to return.  The is based on the storage
-     *                              driver ($driver).  The code is dynamically
-     *                              included.
-     *
      * @param string    $user       The name of the user who owns these tasks.
      *
-     * @param array     $params     (optional) A hash containing any additional
-     *                              configuration or connection parameters a
-     *                              subclass might need.
-     *
      * @return mixed    The created concrete Nag_Driver instance, or false
      *                  on error.
      */
-    function &singleton($driver, $user, $params = null)
+    function &singleton($user)
     {
         static $instances;
 
-        if (is_null($params)) {
-            $params = Horde::getDriverConfig('storage', $driver);
-        }
-
-        if (!isset($instances)) {
-            $instances = array();
-        }
-
-        $signature = serialize(array($driver, $user, $params));
-        if (!isset($instances[$signature])) {
-            $instances[$signature] = &Nag_Driver::factory($driver, $user, $params);
-        }
+	if (!isset($instances[$user])) {
+            $instances[$user] = &Nag_Driver::factory($user);
+	}
 
-        return $instances[$signature];
+        return $instances[$user];
     }
 
     /**
@@ -273,6 +260,139 @@
         foreach ($this->_tasks as $id => $task) {
             $this->_tasks[$id]['flags'] |= TASK_DELETED;
         }
+    }
+
+    /**
+     * Retrieves the user's tasks from the database.
+     *
+     * @return mixed  True on success, PEAR_Error on failure.
+     */
+    function retrieve()
+    {
+        $this->_tasks = array();
+
+        $task_ids = $this->_tasks_category->get(CATEGORY_FORMAT_FLAT);
+        foreach ($task_ids as $task_id => $name) {
+            if ($task_id == "-1") {
+                continue;
+            }
+            $obj = $this->_tasks_category->getCategoryById($task_id);
+            $this->_tasks[$task_id] = array(
+                'task_id'       => $task_id,
+                'tasklist_id'   => $this->_user,
+                'name'          => $obj->getName(),
+                'desc'          => $obj->get('description'),
+                'category'      => $obj->get('category'),
+                'due'           => $obj->get('due'),
+                'priority'      => $obj->get('priority'),
+                'completed'     => $obj->get('completed'),
+                'alarm'         => $obj->get('alarm'),
+                'flags'         => 0
+                );
+        }
+
+        return true;
+    }
+
+    /**
+     * Stores the user's tasks to SQL server.
+     *
+     * @return mixed  True on success, PEAR_Error on failure.
+     */
+    function store()
+    {
+        /* Build lists of the tasks that require pending database operations. */
+        $added_tasks = $this->listTasks(TASK_ADDED);
+        $modified_tasks = $this->listTasks(TASK_MODIFIED);
+        $deleted_tasks = $this->listTasks(TASK_DELETED);
+
+        /* If there are no pending operations, exit successfully now. */
+        if ((count($added_tasks) == 0) && (count($modified_tasks) == 0) &&
+            (count($deleted_tasks) == 0)) {
+            return true;
+        }
+
+        /* Preform any pending deletions. */
+        if (count ($deleted_tasks) > 0) {
+            foreach ($deleted_tasks as $task_id => $task) {
+                $obj = $this->_tasks_category->getCategoryById($task_id);
+                $ret = $this->_tasks_category->removeCategory($obj);
+                if (is_a($ret, 'PEAR_Error')) {
+                    return $ret;
+                }
+            }
+
+            $this->purgeDeleted();
+        }
+
+        /* Perform any pending additions. */
+        if (count($added_tasks) > 0) {
+            foreach ($added_tasks as $task_id => $task) {
+                $obj = &new CategoryObject($task['name']);
+                $obj->set('description', $task['desc']);
+                $obj->set('due', $task['due']);
+                $obj->set('priority', $task['priority']);
+                $obj->set('completed', $task['completed']);
+                $obj->set('category', $task['category']);
+                $obj->set('modified', time());
+                $obj->set('alarm', $task['alarm']);
+                $ret = $this->_tasks_category->addCategory($obj);
+                // XXX: Do we store the task id back?
+                if (is_a($ret,'PEAR_Error')) {
+                    return $ret;
+                }
+
+                /* Clear the ADDED flag. */
+                $this->setFlag($task_id, TASK_ADDED, false);
+            }
+        }
+
+        /* Perform any pending modifications. */
+        if (count($modified_tasks) > 0) {
+            foreach ($modified_tasks as $task_id => $task) {
+                $obj = $this->_tasks_category->getCategoryById($task_id);
+                $obj->set('description', $task['desc']);
+                $obj->set('due', $task['due']);
+                $obj->set('priority', $task['priority']);
+                $obj->set('completed', $task['completed']);
+                $obj->set('category', $task['category']);
+                $obj->set('modified', time());
+                $obj->set('alarm', $task['alarm']);
+                $ret = $this->_tasks_category->updateCategoryData($obj);
+                if (is_a($ret,'PEAR_Error')) {
+                    return $ret;
+                }
+                if ($task['name'] != $obj->getName()) {
+                    $ret = $this->_tasks_category->renameCategory($obj, $task['name']);
+                    if (is_a($ret,'PEAR_Error')) {
+                        return $ret;
+                    }
+                }
+
+                $this->setFlag($task_id, TASK_MODIFIED, false);
+            }
+        }
+
+        return true;
+    }
+
+    function listAlarms($date)
+    {
+        if (count($this->_tasks) == 0) {
+            $ret = $this->retrieve();
+            if (is_a($ret,'PEAR_Error')) {
+                return $ret;
+            }
+        }
+        $now = time();
+        $alarms = array();
+        foreach ($this->_tasks as $task_id => $task) {
+            if ($task['alarm'] > 0 &&
+                ($task['due'] - ($task['alarm']*60)) <= $date) {
+                $alarms[$task_id] = $task; 
+            }
+        }
+        return $alarms;
     }
 
 }
epm diff lib/Nag.php
--- lib/Nag.php	Wed Aug 27 10:31:06 2003
+++ lib/Nag.php	Wed Aug 27 10:32:15 2003
@@ -106,7 +106,7 @@
 
         foreach ($GLOBALS['display_tasklists'] as $tasklist) {
             /* Create a Nag storage instance. */
-            $storage = &Nag_Driver::singleton($conf['storage']['driver'], $tasklist);
+            $storage = &Nag_Driver::singleton($tasklist);
             $storage->retrieve();
 
             /* Retrieve the task list for storage. */
@@ -174,7 +174,7 @@
     {
         global $conf;
 
-        $storage = &Nag_Driver::singleton($conf['storage']['driver'], $tasklist);
+        $storage = &Nag_Driver::singleton($tasklist);
         $storage->retrieve();
         $tasks = $storage->listTasks();
 
@@ -199,7 +199,7 @@
 
         foreach ($GLOBALS['display_tasklists'] as $tasklist) {
             /* Create a Nag storage instance. */
-            $storage = &Nag_Driver::singleton($conf['storage']['driver'], $tasklist);
+            $storage = &Nag_Driver::singleton($tasklist);
             $storage->retrieve();
 
             /* Retrieve the alarms for the task list. */
epm diff config/conf.xml
--- config/conf.xml	Wed Aug 27 10:32:22 2003
+++ config/conf.xml	Wed Aug 27 10:32:43 2003
@@ -16,48 +16,6 @@
    <configstring name="time_format" desc="Time Format used in Task View">%X</configstring>
  </configsection>
 
- <configsection name="storage">
-   <configheader>
-        Storage System Settings
-   </configheader>
-
-  <configenum name="driver" desc="What storage driver should we use?">sql
-   <values>
-    <value>sql</value>
-   </values>
-  </configenum>
-
-  <configsection name="params">
-   <configdescription>
-        Any parameters that the storage driver needs. This includes
-        database or ldap server, username/password to connect with, etc.
-        Sample values are for a MySQL sql driver
-   </configdescription>
-   <configenum name="phptype" desc="What database backend should we use?">mysql
-    <values>
-     <value desc="MySQL">mysql</value>
-     <value desc="PostgreSQL">pgsql</value>
-     <value desc="ODBC">odbc</value>
-     <value desc="Oracle">oci8</value>
-    </values>
-   </configenum>
-   <configenum name="protocol" desc="How should we connect to the database?">unix
-    <values>
-     <value desc="UNIX Sockets">unix</value>
-     <value desc="TCP/IP">tcp</value>
-    </values>
-   </configenum>
-   <configstring name="hostspec" desc="Database server/host/ODBC dsn">localhost</configstring>
-   <configstring name="username" desc="Username to connect to the database as">horde</configstring>
-   <configpassword name="password" required="false" desc="Password to connect with">****</configpassword>
-   <configstring name="database" desc="Database name to use">horde</configstring>
-   <configstring name="socket" required="false" desc="Location of UNIX socket, if using one">/var/lib/mysql/mysql.sock</configstring>
-   <configinteger name="port" required="false" desc="Port the DB is running on, if non-standard">3306</configinteger>
-   <configstring name="table" desc="Database table">nag_tasks</configstring>
-   <configstring name="charset" desc="Internally used charset">iso-8859-1</configstring>
-  </configsection>
- </configsection>
-
  <configsection name="menu">
    <configheader>
         Menu settings
epm diff scripts/drivers/nag_tasks.sql
--- scripts/drivers/nag_tasks.sql	2003-08-27 10:50:39.000000000 -0400
+++ scripts/drivers/nag_tasks.sql	1969-12-31 19:00:00.000000000 -0500
@@ -1,19 +0,0 @@
--- $Horde: nag/scripts/drivers/nag_tasks.sql,v 1.9 2003/02/21 18:04:18 chuck Exp $
-
-CREATE TABLE nag_tasks (
-    task_owner      VARCHAR(255) NOT NULL,
-    task_id         INT NOT NULL,
-    task_name       VARCHAR(64) NOT NULL,
-    task_desc       TEXT NULL,
-    task_modified   INT NOT NULL,
-    task_due        INT NULL,
-    task_priority   INT NOT NULL DEFAULT 0,
-    task_category   INT NOT NULL DEFAULT 0,
-    task_completed  SMALLINT NOT NULL DEFAULT 0,
-    task_private    SMALLINT NOT NULL DEFAULT 1,
-    task_alarm      INT NOT NULL DEFAULT 0,
-
-    PRIMARY KEY (task_owner, task_id)
-);
-
-GRANT SELECT, INSERT, UPDATE, DELETE ON nag_tasks TO horde;
epm diff scripts/category_update.php
--- scripts/category_update.php	1969-12-31 19:00:00.000000000 -0500
+++ scripts/category_update.php	2003-08-27 13:19:19.000000000 -0400
@@ -0,0 +1,91 @@
+<?php
+/**
+ * $Horde: $
+ *
+ * Copyright 2003 Cronosys, LLC <http://www.cronosys.com/>
+ *
+ * See the enclosed file COPYING for license information (GPL).  If you
+ * did not receive this file, see http://www.fsf.org/copyleft/gpl.html.
+ */
+
+/* This script pulls tasks from the old nag database format and puts them into
+ * the category driver. */
+
+ at define('HORDE_BASE', dirname(__FILE__) . '/../..');
+
+// Do CLI checks and environment setup first.
+require_once HORDE_BASE . '/lib/CLI.php';
+
+// Make sure no one runs this from the web.
+if (!Horde_CLI::runningFromCLI()) {
+    exit("Must be run from the command line\n");
+}
+
+// Load the CLI environment - make sure there's no time limit, init
+// some variables, etc.
+Horde_CLI::init();
+
+// Registry
+require_once HORDE_BASE . '/lib/Registry.php';
+$registry = &Registry::singleton();
+$registry->pushApp('nag');
+$conf = &$GLOBALS['conf'];
+
+require_once HORDE_BASE . '/lib/Category.php'; 
+require_once HORDE_BASE . '/lib/Notification.php';
+$notification = &Notification::singleton();
+
+require_once HORDE_BASE . '/lib/Auth.php';
+
+$params = Horde::getDriverConfig('auth', $conf['auth']['driver']);
+$auth = &Auth::singleton($conf['auth']['driver'], $params);
+
+ at define('NAG_BASE', dirname(__FILE__) . '/..');
+require_once NAG_BASE . '/lib/Nag.php';
+require_once NAG_BASE . '/lib/Driver.php';
+
+require_once 'DB.php';
+
+$params = $conf['storage']['params'];
+$charset = $params['charset'];
+$db = &DB::connect($conf['storage']['params']);
+if (is_a($db,'PEAR_Error')) {
+    die($db->getMessage());
+}
+
+$q = sprintf('SELECT * FROM %s;', $conf['storage']['params']['table']);
+$qr = $db->getAll($q, DB_FETCHMODE_ASSOC);
+if (is_a($qr, 'PEAR_Error')) {
+    die($qr->getMessage());
+}
+
+// We just use the driver to get the category object, the user isn't important.
+$driver = &Nag_Driver::singleton('foo');
+
+foreach ($qr as $row) {
+    $obj = &new CategoryObject(String::convertCharset($row['task_name'], $charset));
+    $obj->set('description', String::convertCharset($row['task_desc'], $charset));
+
+    if ($auth->exists($row['task_owner'])) {
+        Auth::setAuth($row['task_owner'], array());
+    } else {
+        // Hope this works!
+        Auth::setAuth('admin');
+    }
+    $obj->set('tasklist', $row['task_owner']);
+    $obj->set('category', $row['task_category']);
+    $obj->set('due', $row['task_due']);
+    $obj->set('priority', $row['task_priority']);
+    $obj->set('completed', $row['task_completed']);
+    $obj->set('alarm', $row['task_alarm']);
+
+    $ret = $driver->_tasks_category->addCategory($obj); 
+    if (is_a($ret, 'PEAR_Error')) {
+        die($ret->getMessage());
+    }
+}
+
+$db->query(sprintf ("DROP TABLE %s;\n", $conf['storage']['params']['table']));
+
+echo "** Tasks successfully upgraded! ***\n";
+exit;
epm diff docs/INSTALL
--- docs/INSTALL	Wed Aug 27 13:20:28 2003
+++ docs/INSTALL	Wed Aug 27 13:22:22 2003
@@ -43,10 +43,10 @@
      Be sure to have completed all of the steps in the INSTALL
      file for the Horde Framework before installing Nag.
 
-  2. SQL support in PHP.
+  2. A configured Horde category driver.
 
-     Nag store its data in an SQL database. Build PHP with whichever
-     SQL driver you require; see the Horde INSTALL file for details.
+     Nag stores its tasks in the configured Horde category driver, so make
+     sure that one is configured.
 
 
 INSTALLING Nag
@@ -86,23 +86,7 @@
       update the 'fileroot' and 'webroot' settings to their correct
       values.
 
-2. Creating the database table
-
-   The specific steps to create the Nag database table depend
-   on which database you've chosen to use.
-
-   First, look in scripts/drivers/ to see if a script already
-   exists for your database type. If so, you should be
-   able to simply execute that script as superuser in your
-   database. (Note that executing the script as the "horde" user will
-   probably fail when granting privileges.)
-
-   If such a script does not exist, you'll need to build your own, using
-   the file nag_tasks.sql as a starting point. If you need
-   assistance in creating databases, you may wish to let us know on
-   the Nag mailing list.
-
-3. Configuring Nag.
+2. Configuring Nag.
 
    To configure Nag, change to the config/ directory of the
    installed distribution, and make copies of all of the configuration
@@ -136,7 +120,7 @@
    trouble using a provided translation, please see the horde/docs/TRANSLATIONS
    file for instructions.
 
-4. Testing Nag
+3. Testing Nag
 
    Use Nag to create, modify, and delete todos. Test at
    least the following:


More information about the nag mailing list