[nag] [patch] Make nag use category driver

Jason M. Felice jfelice at cronosys.com
Thu Aug 28 09:54:39 PDT 2003


On Wed, Aug 27, 2003 at 11:06:24PM -0400, Chuck Hagenbuch wrote:
> Quoting "Jason M. Felice" <jfelice at cronosys.com>:
>
> Having thought about this a bit more, it'd be even better if this could be
> provided as a different driver option, keeping the SQL driver. That way
> alternate drivers, like the Kolab driver that someone was working on, will
> still be possible, but the simplicity of using the category backend would be
> available for default installs, etc.
> 
> It actually looks like this would be a relatively simple change of your patch.
> Whatcha think? :)

Attached.

-- 
 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	Wed Aug 27 14:05:18 2003
+++ lib/Driver/sql.php	Thu Aug 28 12:39:49 2003
@@ -237,32 +237,6 @@
         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. */
epm diff lib/Driver.php
--- lib/Driver.php	Wed Aug 27 14:05:18 2003
+++ lib/Driver.php	Thu Aug 28 12:35:42 2003
@@ -275,4 +275,23 @@
         }
     }
 
+    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 config/conf.xml
--- config/conf.xml	Wed Aug 27 14:05:18 2003
+++ config/conf.xml	Thu Aug 28 12:38:28 2003
@@ -21,8 +21,9 @@
         Storage System Settings
    </configheader>
 
-  <configenum name="driver" desc="What storage driver should we use?">sql
+  <configenum name="driver" desc="What storage driver should we use?">category
    <values>
+    <value>category</value>
     <value>sql</value>
    </values>
   </configenum>
@@ -33,7 +34,7 @@
         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
+   <configenum name="phptype" desc="What database backend should we use (sql driver only)?">mysql
     <values>
      <value desc="MySQL">mysql</value>
      <value desc="PostgreSQL">pgsql</value>
@@ -41,20 +42,20 @@
      <value desc="Oracle">oci8</value>
     </values>
    </configenum>
-   <configenum name="protocol" desc="How should we connect to the database?">unix
+   <configenum name="protocol" desc="How should we connect to the database (sql driver only)?">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>
+   <configstring name="hostspec" desc="Database server/host/ODBC dsn (sql driver only)">localhost</configstring>
+   <configstring name="username" desc="Username to connect to the database as (sql driver only)">horde</configstring>
+   <configpassword name="password" required="false" desc="Password to connect with (sql driver only)">****</configpassword>
+   <configstring name="database" desc="Database name to use (sql driver only)">horde</configstring>
+   <configstring name="socket" required="false" desc="Location of UNIX socket, if using one (sql driver only)">/var/lib/mysql/mysql.sock</configstring>
+   <configinteger name="port" required="false" desc="Port the DB is running on, if non-standard (sql driver only)">3306</configinteger>
+   <configstring name="table" desc="Database table (sql driver only)">nag_tasks</configstring>
+   <configstring name="charset" desc="Internally used charset (sql driver only)">iso-8859-1</configstring>
   </configsection>
  </configsection>
 
epm diff scripts/category_update.php
--- scripts/category_update.php	1969-12-31 19:00:00.000000000 -0500
+++ scripts/category_update.php	2003-08-28 12:48:17.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 converted to Category driver! ***\n";
+exit;
epm diff docs/INSTALL
--- docs/INSTALL	Wed Aug 27 14:05:18 2003
+++ docs/INSTALL	Thu Aug 28 12:53:51 2003
@@ -43,10 +43,11 @@
      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. SQL support in PHP _or_ a configured 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 will store its data in either an SQL database or the Horde Category
+     driver. If you use SQL, build PHP with whichever SQL driver you require;
+     see the Horde INSTALL file for details.
 
 
 INSTALLING Nag
@@ -89,7 +90,8 @@
 2. Creating the database table
 
    The specific steps to create the Nag database table depend
-   on which database you've chosen to use.
+   on which database you've chosen to use.  If you've chosen to use the
+   Horde category driver, skip this step.
 
    First, look in scripts/drivers/ to see if a script already
    exists for your database type. If so, you should be
epm diff lib/Driver/category.php
--- lib/Driver/category.php	1969-12-31 19:00:00.000000000 -0500
+++ lib/Driver/category.php	2003-08-28 12:49:26.000000000 -0400
@@ -0,0 +1,156 @@
+<?php
+/**
+ * Nag storage implementation for the Horde Category driver.
+ *
+ * $Horde: $
+ *
+ * @author  Jay 'Eraserhead' Felice <jfelice at cronosys.com>
+ * @version $Revision: 1.41 $
+ * @since   Nag 3.0
+ * @package nag
+ */
+class Nag_Driver_category extends Nag_Driver {
+
+    /** Hash containing connection parameters. */
+    var $_params = array();
+
+    /**
+     * Reference to the category instance.
+     * @var object $tasks_category
+     */
+    var $_tasks_category = null;
+
+    /**
+     * 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_category($user, $params = array())
+    {
+        global $conf;
+
+        $this->_user = $user;
+        $this->_params = $params;
+
+        $driver = $conf['category']['driver'];
+        $params = Horde::getDriverConfig('category', $driver);
+        $params = array_merge($params, array( 'group' => 'nag.tasks' ));
+
+        $this->_tasks_category = &Category::singleton($driver, $params);
+    }
+
+    /**
+     * Retrieves the user's tasks from the Category driver.
+     *
+     * @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 Category driver.
+     *
+     * @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);
+                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;
+    }
+
+}


More information about the nag mailing list