Kronolith_Geo drivers now use Horde_Db and DI
authorMichael J. Rubinsky <mrubinsk@horde.org>
Thu, 13 Jan 2011 05:36:18 +0000 (00:36 -0500)
committerMichael J. Rubinsky <mrubinsk@horde.org>
Thu, 13 Jan 2011 05:36:18 +0000 (00:36 -0500)
kronolith/lib/Application.php
kronolith/lib/Driver/Sql.php
kronolith/lib/Event.php
kronolith/lib/Geo.php [deleted file]
kronolith/lib/Geo/Base.php [new file with mode: 0644]
kronolith/lib/Geo/Mysql.php
kronolith/lib/Geo/Sql.php
kronolith/lib/Injector/Factory/Driver.php
kronolith/lib/Injector/Factory/Geo.php [new file with mode: 0644]
kronolith/lib/Kronolith.php

index 249e355..0e5d49e 100644 (file)
@@ -72,6 +72,8 @@ class Kronolith_Application extends Horde_Registry_Application
             throw new Horde_Exception('The Content_Tagger class could not be found. Make sure the registry entry for the Content system is present.');
         }
 
+        $GLOBALS['injector']->bindFactory('Kronolith_Geo', 'Kronolith_Injector_Factory_Geo', 'create');
+
         /* Set the timezone variable, if available. */
         $GLOBALS['registry']->setTimeZone();
 
index f1220ac..d37d4d2 100644 (file)
@@ -564,8 +564,10 @@ class Kronolith_Driver_Sql extends Kronolith_Driver
         $this->_updateTags($event);
 
         /* Update Geolocation */
-        if ($gDriver = Kronolith::getGeoDriver()) {
-            $gDriver->setLocation($event->id, $event->geoLocation);
+        try {
+            $GLOBALS['injector']->getInstance('Kronolith_Geo')->setLocation($event->id, $event->geoLocation);
+        } catch (Kronolith_Exception $e) {
+
         }
 
         /* Notify users about the changed event. */
@@ -621,8 +623,12 @@ class Kronolith_Driver_Sql extends Kronolith_Driver
         $this->_addTags($event);
 
         /* Update Geolocation */
-        if ($event->geoLocation && $gDriver = Kronolith::getGeoDriver()) {
-            $gDriver->setLocation($event->id, $event->geoLocation);
+        if ($event->geoLocation) {
+            try {
+                $GLOBALS['injector']->getInstance('Kronolith_Geo')->setLocation($event->id, $event->geoLocation);
+            } catch (Kronolith_Exception $e) {
+
+            }
         }
 
         /* Notify users about the new event. */
@@ -781,8 +787,9 @@ class Kronolith_Driver_Sql extends Kronolith_Driver
         $tagger->replaceTags($event->uid, array(), $event->creator, 'event');
 
         /* Remove any geolocation data */
-        if ($gDriver = Kronolith::getGeoDriver()) {
-            $gDriver->deleteLocation($event->id);
+        try {
+            $GLOBALS['injector']->getInstance('Kronolith_Geo')->deleteLocation($event->id);
+        } catch (Kronolith_Exception $e) {
         }
 
         /* Notify about the deleted event. */
index 467e08e..9a4b40f 100644 (file)
@@ -365,11 +365,10 @@ abstract class Kronolith_Event
             }
             return $this->_tags;
         case 'geoLocation':
-            if (!isset($this->_geoLocation) &&
-                ($gDriver = Kronolith::getGeoDriver())) {
+            if (!isset($this->_geoLocation)) {
                 try {
-                    $this->_geoLocation = $gDriver->getLocation($this->id);
-                } catch (Exception $e) {}
+                    $this->_geoLocation = $GLOBALS['injector']->getInstance('Kronolith_Geo')->getLocation($this->id);
+                } catch (Kronolith_Exception $e) {}
             }
             return $this->_geoLocation;
         }
diff --git a/kronolith/lib/Geo.php b/kronolith/lib/Geo.php
deleted file mode 100644 (file)
index e2bbbab..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-<?php
-/**
- * Storage driver for Kronolith's Geo location data.
- *
- * Copyright 2009-2010 The Horde Project (http://www.horde.org/)
- *
- * See the enclosed file COPYING for license information (GPL). If you
- * did not receive this file, see http://www.fsf.org/copyleft/gpl.html.
- *
- * @author  Michael J. Rubinsky <mrubinsk@horde.org>
- *
- * @package Kronolith
- */
-abstract class Kronolith_Geo
-{
-    protected $_params;
-
-    public function __construct($params = array())
-    {
-        $this->_params = $params;
-    }
-
-    /**
-     * Obtain a Kronolith_Geo object. Currently all drivers are SQL based,
-     * so use the sql config by default.
-     *
-     * @param string $driver  The type of object to return
-     * @param unknown_type $params  Any driver specific parameters
-     *
-     * @return Kronolith_Geo
-     * @throws Kronolith_Exception
-     */
-    static public function factory($driver = null, $params = array())
-    {
-        $driver = basename($driver);
-        $class = 'Kronolith_Geo_' . $driver;
-        $driver = new $class(Horde::getDriverConfig('calendar', 'sql'));
-        $driver->initialize();
-        return $driver;
-    }
-
-    abstract public function setLocation($event_id, $point);
-    abstract public function getLocation($event_id);
-    abstract public function deleteLocation($event_id);
-    abstract public function search($criteria);
-}
\ No newline at end of file
diff --git a/kronolith/lib/Geo/Base.php b/kronolith/lib/Geo/Base.php
new file mode 100644 (file)
index 0000000..d557338
--- /dev/null
@@ -0,0 +1,72 @@
+<?php
+/**
+ * Storage driver for Kronolith's Geo location data.
+ *
+ * Copyright 2009-2010 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (GPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/gpl.html.
+ *
+ * @author  Michael J. Rubinsky <mrubinsk@horde.org>
+ *
+ * @package Kronolith
+ */
+abstract class Kronolith_Geo_Base
+{
+    /**
+     *
+     * @var Horde_Db_Adapter
+     */
+    protected $_db;
+
+    /**
+     *
+     * @param Horde_Db_Adapter $adapter  The Horde_Db adapter
+     *
+     * @return Kronolith_Geo_Base
+     */
+    public function __construct(Horde_Db_Adapter $adapter)
+    {
+        $this->_db = $adapter;
+    }
+
+    /**
+     * Save location of event to storage
+     *
+     * @param string $event_id  The event id
+     * @param array  $point     Hash containing 'lat' and 'lon' coordinates
+     */
+    abstract public function setLocation($event_id, $point);
+
+    /**
+     * Retrieve the location of the specified event.
+     *
+     * @param string $event_id  The event id
+     *
+     * @return array  A hash containing 'lat' and 'lon'
+     */
+    abstract public function getLocation($event_id);
+
+    /**
+     * Removes the event's location from storage.
+     *
+     * @param string $event_id  The event it.
+     */
+    abstract public function deleteLocation($event_id);
+
+    /**
+     * Search for events close to a given point.
+     *
+     * @param array $criteria  An array of:
+     *<pre>
+     * point  - lat/lon hash
+     * radius - the radius to search in
+     * limit  - limit the number of hits
+     * factor - Conversion factor for miles per distance unit [default is 69].
+     *</pre>
+     *
+     * @return array of event ids with locations near the specified criteria.
+     */
+    abstract public function search($criteria);
+
+}
\ No newline at end of file
index dd99e41..fc6152c 100644 (file)
@@ -20,19 +20,18 @@ class Kronolith_Geo_Mysql extends Kronolith_Geo_Sql
     /**
      * Set the location of the specified event _id
      *
-     * @see kronolith/lib/Driver/Kronolith_Driver_Geo#setLocation($event_id, $point)
+     * @see Kronolith_Geo_Base#setLocation()
      * @throws Kronolith_Exception
      */
     public function setLocation($event_id, $point)
     {
         /* First make sure it doesn't already exist */
         $sql = 'SELECT COUNT(*) FROM kronolith_events_geo WHERE event_id = ?';
-        Horde::logMessage(sprintf('Kronolith_Geo_Mysql::setLocation(): user = "%s"; query = "%s"; values = "%s"',
-            $GLOBALS['registry']->getAuth(), $sql, $event_id), 'DEBUG');
-        $count = $this->_db->getOne($sql, array($event_id));
-        if ($count instanceof PEAR_Error) {
-            Horde::logMessage($count, 'ERR');
-            throw new Horde_Exception($count);
+
+        try {
+            $count = $this->_db->selectValue($sql, array($event_id));
+        } catch (Horde_Db_Exception $e) {
+            throw new Kronolith_Exception($e);
         }
 
         /* Do we actually have data? */
@@ -56,15 +55,12 @@ class Kronolith_Geo_Mysql extends Kronolith_Geo_Sql
         }
         $sql = sprintf($sql, $point['lat'], $point['lon']);
         $values = array($point['zoom'], $event_id);
-        Horde::logMessage(sprintf('Kronolith_Geo_Mysql::setLocation(): user = "%s"; query = "%s"; values = "%s"',
-                                  $GLOBALS['registry']->getAuth(), $sql, implode(',', $values)), 'DEBUG');
-        $result = $this->_write_db->query($sql, $values);
-        if ($result instanceof PEAR_Error) {
-            Horde::logMessage($result, 'ERR');
-            throw new Horde_Exception($result);
-        }
 
-        return $result;
+        try {
+            $this->_db->execute($sql, $values);
+        } catch (Horde_Db_Error $e) {
+            throw new Kronolith_Exception($e);
+        }
     }
 
     /**
@@ -76,14 +72,11 @@ class Kronolith_Geo_Mysql extends Kronolith_Geo_Sql
     public function getLocation($event_id)
     {
         $sql = 'SELECT x(event_coordinates) as lat, y(event_coordinates) as lon, event_zoom as zoom FROM kronolith_events_geo WHERE event_id = ?';
-        Horde::logMessage(sprintf('Kronolith_Geo_Mysql::getLocation(): user = "%s"; query = "%s"; values = "%s"',
-            $GLOBALS['registry']->getAuth(), $sql, $event_id), 'DEBUG');
-        $result = $this->_db->getRow($sql, array($event_id), DB_FETCHMODE_ASSOC);
-        if ($result instanceof PEAR_Error) {
-            Horde::logMessage($result, 'ERR');
-            throw new Horde_Exception($result);
+        try {
+            return $this->_db->selectOne($sql, array($event_id));
+        } catch (Horde_Db_Exception $e) {
+            throw new Kronolith_Exception($e);
         }
-        return $result;
     }
 
     /**
@@ -113,15 +106,13 @@ class Kronolith_Geo_Mysql extends Kronolith_Geo_Sql
                . "GLength(LINESTRINGFromWKB(LineString(event_coordinates, GeomFromText('POINT(" . (float)$point['lat'] . " " . (float)$point['lon'] . ")')))) * ? as distance, "
                . "x(event_coordinates) as lat, y(event_coordinates) as lon FROM kronolith_events_geo HAVING distance < ?  ORDER BY distance ASC LIMIT ?";
 
-        Horde::logMessage(sprintf('Kronolith_Geo_Mysql::search(): user = "%s"; query = "%s"; values = "%s"',
-            $GLOBALS['registry']->getAuth(), $sql, print_r($params, true)), 'DEBUG');
-
-        $results = $this->_db->getAssoc($sql, false, $params, DB_FETCHMODE_ASSOC);
-        if ($results instanceof PEAR_Error) {
-            Horde::logMessage($results, 'ERR');
-            throw new Horde_Exception($results);
+        try {
+            $results = $this->_db->selectAll($sql, $params);
+        } catch (Horde_Db_Exception $e) {
+            throw new Kronolith_Exception($e);
         }
 
         return $results;
     }
+
 }
index b3776f9..fd2d26c 100644 (file)
  * @category Horde
  * @package  Kronolith
  */
-class Kronolith_Geo_Sql extends Kronolith_Geo
+class Kronolith_Geo_Sql extends Kronolith_Geo_Base
 {
-    protected $_write_db;
-    protected $_db;
-
     /**
-     * @throws Kronolith_Exception
+     * @var Horde_Db_Adapter
      */
-    public function initialize()
-    {
-        try {
-            $this->_db = $GLOBALS['injector']->getInstance('Horde_Core_Factory_DbPear')->create('read', 'kronolith', 'calendar');
-            $this->_write_db = $GLOBALS['injector']->getInstance('Horde_Core_Factory_DbPear')->create('rw', 'kronolith', 'calendar');
-        } catch (Horde_Exception $e) {
-            throw new Kronolith_Exception($e);
-        }
-
-        return true;
-    }
+    protected $_db;
 
     /**
      * Set the location of the specified event _id
      *
-     * @see kronolith/lib/Driver/Kronolith_Driver_Geo#setLocation($event_id, $point)
+     * @see Kronolith_Geo_Base#setLocation()
      * @throws Kronolith_Exception
      */
     public function setLocation($event_id, $point)
     {
         /* First make sure it doesn't already exist */
         $sql = 'SELECT COUNT(*) FROM kronolith_events_geo WHERE event_id = ?';
-        Horde::logMessage(sprintf('Kronolith_Geo_Sql::setLocation(): user = "%s"; query = "%s"; values = "%s"',
-            $GLOBALS['registry']->getAuth(), $sql, $event_id), 'DEBUG');
-        $count = $this->_db->getOne($sql, array($event_id));
-        if ($count instanceof PEAR_Error) {
-            Horde::logMessage($count, 'ERR');
-            throw new Horde_Exception($count);
+        try {
+            $count = $this->_db->selectValue($sql, array($event_id));
+        } catch (Horde_Db_Exception $e) {
+            throw new Kronolith_Exception($e);
         }
 
         /* Do we actually have data? If not, see if we are deleting an
@@ -71,41 +56,33 @@ class Kronolith_Geo_Sql extends Kronolith_Geo
         } else {
             $sql = 'INSERT into kronolith_events_geo (event_lat, event_lon, event_zoom, event_id) VALUES(?, ?, ?, ?)';
         }
-        Horde::logMessage(sprintf('Kronolith_Geo_Sql::setLocation(): user = "%s"; query = "%s"; values = "%s"',
-                    $GLOBALS['registry']->getAuth(), $sql, print_r($params, true)), 'DEBUG');
-        $result = $this->_write_db->query($sql, $params);
-        if ($result instanceof PEAR_Error) {
-            Horde::logMessage($result, 'ERR');
-            throw new Horde_Exception($result);
+        try {
+            $this->_db->execute($sql, $params);
+        } catch (Horde_Db_Exception $e) {
+            throw new Horde_Exception($e);
         }
-
-        return $result;
     }
 
     /**
      * Get the location of the provided event_id.
      *
-     * @see kronolith/lib/Driver/Kronolith_Driver_Geo#getLocation($event_id)
+     * @see Kronolith_Geo_Base#getLocation()
      * @throws Kronolith_Exception
      */
     public function getLocation($event_id)
     {
         $sql = 'SELECT event_lat as lat, event_lon as lon, event_zoom as zoom FROM kronolith_events_geo WHERE event_id = ?';
-        Horde::logMessage(sprintf('Kronolith_Geo_Sql::getLocation(): user = "%s"; query = "%s"; values = "%s"',
-                    $GLOBALS['registry']->getAuth(), $sql, $event_id), 'DEBUG');
-        $result = $this->_db->getRow($sql, array($event_id), DB_FETCHMODE_ASSOC);
-        if ($result instanceof PEAR_Error) {
-            Horde::logMessage($result, 'ERR');
-            throw new Horde_Exception($result);
+        try {
+            return $this->_db->selectOne($sql, array($event_id));
+        } catch (Horde_Db_Exception $e) {
+            throw new Kronolith_Exception($e);
         }
-
-        return $result;
     }
 
     /**
      * Deletes an entry from storage
      *
-     * @see kronolith/lib/Driver/Kronolith_Driver_Geo#removeLocation($event_id)
+     * @see Kronolith_Geo_Base#removeLocation()
      *
      * @param string $event_id
      *
@@ -114,12 +91,10 @@ class Kronolith_Geo_Sql extends Kronolith_Geo
     public function deleteLocation($event_id)
     {
         $sql = 'DELETE FROM kronolith_events_geo WHERE event_id = ?';
-        Horde::logMessage(sprintf('Kronolith_Geo_Sql::deleteLocation(): user = "%s"; query = "%s"; values = "%s"',
-                    $GLOBALS['registry']->getAuth(), $sql, $event_id), 'DEBUG');
-        $result = $this->_write_db->query($sql, array($event_id));
-        if ($result instanceof PEAR_Error) {
-            Horde::logMessage($result, 'ERR');
-            throw new Horde_Exception($result);
+        try {
+            $this->_db->delete($sql, array($event_id));
+        } catch (Horde_Db_Exception $e) {
+            throw new Horde_Exception($e);
         }
     }
 
@@ -129,7 +104,7 @@ class Kronolith_Geo_Sql extends Kronolith_Geo
      * TODO: If all we really use the geodata for is distance, it really doesn't
      *       make sense to use the GIS extensions since the distance calculations
      *       are done with Euclidian geometry ONLY ... and therefore will give
-     *       incorrect results when done on a geocentric coordinate system...
+     *       incorrect results when done on a geocentric coordinate system.
      *       They might be useful if we eventually want to do searches on
      *       MBRs
      *
index 72e5a63..4b8bb60 100644 (file)
@@ -60,5 +60,5 @@ class Kronolith_Injector_Factory_Driver
 
         return $driver;
     }
+
 }
\ No newline at end of file
diff --git a/kronolith/lib/Injector/Factory/Geo.php b/kronolith/lib/Injector/Factory/Geo.php
new file mode 100644 (file)
index 0000000..56e8e4a
--- /dev/null
@@ -0,0 +1,38 @@
+<?php
+/**
+ * Horde_Injector based factory for Kronolith_Geo drivers
+ *
+ * @author Michael J Rubinsky <mrubinsk@horde.org>
+ * @package Kronolith
+ */
+class Kronolith_Injector_Factory_Geo
+{
+    /**
+     * Instances.
+     *
+     * @var array
+     */
+    private $_instances = array();
+
+    /**
+     * Return the driver instance.
+     *
+     * @return Kronolith_Storage
+     * @throws Kronolith_Exception
+     */
+    public function create(Horde_Injector $injector)
+    {
+        if (empty($this->_instances[$GLOBALS['conf']['maps']['geodriver']])) {
+            if (!empty($GLOBALS['conf']['maps']['geodriver'])) {
+                $class = 'Kronolith_Geo_' . $GLOBALS['conf']['maps']['geodriver'];
+                $db = $injector->getInstance('Horde_Db_Adapter');
+                $this->_instances[$GLOBALS['conf']['maps']['geodriver']] = new $class($db);
+            } else {
+                throw new Kronolith_Exception(_("Geospatial support not configured."));
+            }
+        }
+
+        return $this->_instances[$GLOBALS['conf']['maps']['geodriver']];
+    }
+
+}
\ No newline at end of file
index 3b2e00b..383a8bb 100644 (file)
@@ -2966,18 +2966,6 @@ class Kronolith
         return self::$_tagger;
     }
 
-    public static function getGeoDriver()
-    {
-        if (!empty($GLOBALS['conf']['maps']['geodriver'])) {
-            try {
-                return Kronolith_Geo::factory($GLOBALS['conf']['maps']['geodriver']);
-            } catch (Exception $e) {
-                Horde::logMessage($e, 'ERR');
-            }
-        }
-        return false;
-    }
-
     /**
      * Obtain an internal calendar. Use this where we don't know if we will
      * have a Horde_Share or a Kronolith_Resource based calendar.