Abstract -> Base
authorJan Schneider <jan@horde.org>
Mon, 7 Sep 2009 08:25:15 +0000 (10:25 +0200)
committerJan Schneider <jan@horde.org>
Mon, 7 Sep 2009 08:25:15 +0000 (10:25 +0200)
23 files changed:
framework/Db/lib/Horde/Db/Adapter/Abstract/Column.php [deleted file]
framework/Db/lib/Horde/Db/Adapter/Abstract/ColumnDefinition.php [deleted file]
framework/Db/lib/Horde/Db/Adapter/Abstract/Index.php [deleted file]
framework/Db/lib/Horde/Db/Adapter/Abstract/Schema.php [deleted file]
framework/Db/lib/Horde/Db/Adapter/Abstract/Table.php [deleted file]
framework/Db/lib/Horde/Db/Adapter/Abstract/TableDefinition.php [deleted file]
framework/Db/lib/Horde/Db/Adapter/Base.php
framework/Db/lib/Horde/Db/Adapter/Base/Column.php [new file with mode: 0644]
framework/Db/lib/Horde/Db/Adapter/Base/ColumnDefinition.php [new file with mode: 0644]
framework/Db/lib/Horde/Db/Adapter/Base/Index.php [new file with mode: 0644]
framework/Db/lib/Horde/Db/Adapter/Base/Schema.php [new file with mode: 0644]
framework/Db/lib/Horde/Db/Adapter/Base/Table.php [new file with mode: 0644]
framework/Db/lib/Horde/Db/Adapter/Base/TableDefinition.php [new file with mode: 0644]
framework/Db/lib/Horde/Db/Adapter/Mssql/Schema.php
framework/Db/lib/Horde/Db/Adapter/Mysql/Column.php
framework/Db/lib/Horde/Db/Adapter/Mysql/Schema.php
framework/Db/lib/Horde/Db/Adapter/Mysqli.php
framework/Db/lib/Horde/Db/Adapter/Oracle/Schema.php
framework/Db/lib/Horde/Db/Adapter/Postgresql/Column.php
framework/Db/lib/Horde/Db/Adapter/Postgresql/Schema.php
framework/Db/lib/Horde/Db/Adapter/Sqlite/Column.php
framework/Db/lib/Horde/Db/Adapter/Sqlite/Schema.php
framework/Db/package.xml

diff --git a/framework/Db/lib/Horde/Db/Adapter/Abstract/Column.php b/framework/Db/lib/Horde/Db/Adapter/Abstract/Column.php
deleted file mode 100644 (file)
index 4536f30..0000000
+++ /dev/null
@@ -1,359 +0,0 @@
-<?php
-/**
- * Copyright 2007 Maintainable Software, LLC
- * Copyright 2008-2009 The Horde Project (http://www.horde.org/)
- *
- * @author     Mike Naberezny <mike@maintainable.com>
- * @author     Derek DeVries <derek@maintainable.com>
- * @author     Chuck Hagenbuch <chuck@horde.org>
- * @license    http://opensource.org/licenses/bsd-license.php
- * @category   Horde
- * @package    Horde_Db
- * @subpackage Adapter
- */
-
-/**
- * @author     Mike Naberezny <mike@maintainable.com>
- * @author     Derek DeVries <derek@maintainable.com>
- * @author     Chuck Hagenbuch <chuck@horde.org>
- * @license    http://opensource.org/licenses/bsd-license.php
- * @category   Horde
- * @package    Horde_Db
- * @subpackage Adapter
- */
-class Horde_Db_Adapter_Abstract_Column
-{
-    protected $_name;
-    protected $_type;
-    protected $_null;
-    protected $_limit;
-    protected $_precision;
-    protected $_scale;
-    protected $_default;
-    protected $_sqlType;
-    protected $_isText;
-    protected $_isNumber;
-
-
-    /*##########################################################################
-    # Construct/Destruct
-    ##########################################################################*/
-
-    /**
-     * Construct
-     *
-     * @param   string  $name     The column's name, such as <tt>supplier_id</tt> in <tt>supplier_id int(11)</tt>.
-     * @param   string  $default  The type-casted default value, such as +new+ in <tt>sales_stage varchar(20) default 'new'</tt>.
-     * @param   string  $sqlType  Only used to extract the column's length, if necessary. For example +60+ in <tt>company_name varchar(60)</tt>.
-     * @param   boolean $null     Determines if this column allows +NULL+ values.
-     */
-    public function __construct($name, $default, $sqlType = null, $null = true)
-    {
-        $this->_name      = $name;
-        $this->_sqlType   = $sqlType;
-        $this->_null      = $null;
-        $this->_limit     = $this->_extractLimit($sqlType);
-        $this->_precision = $this->_extractPrecision($sqlType);
-        $this->_scale     = $this->_extractScale($sqlType);
-        $this->_type      = $this->_simplifiedType($sqlType);
-        $this->_default   = $this->extractDefault($default);
-
-        $this->_isText    = $this->_type == 'text'  || $this->_type == 'string';
-        $this->_isNumber  = $this->_type == 'float' || $this->_type == 'integer' || $this->_type == 'decimal';
-    }
-
-    /**
-     * @return  boolean
-     */
-    public function isText()
-    {
-        return $this->_isText;
-    }
-
-    /**
-     * @return  boolean
-     */
-    public function isNumber()
-    {
-        return $this->_isNumber;
-    }
-
-    /**
-     * Casts value (which is a String) to an appropriate instance.
-     */
-    public function typeCast($value)
-    {
-        if ($value === null) return null;
-
-        switch ($this->_type) {
-        case 'string':
-        case 'text':
-            return $value;
-        case 'integer':
-            return strlen($value) ? (int)$value : null;
-        case 'float':
-            return strlen($value) ? (float)$value : null;
-        case 'decimal':
-            return $this->valueToDecimal($value);
-        case 'datetime':
-        case 'timestamp':
-            return $this->stringToTime($value);
-        case 'time':
-            return $this->stringToDummyTime($value);
-        case 'date':
-            return $this->stringToDate($value);
-        case 'binary':
-            return $this->binaryToString($value);
-        case 'boolean':
-            return $this->valueToBoolean($value);
-        default:
-            return $value;
-        }
-    }
-
-    public function extractDefault($default)
-    {
-        return $this->typeCast($default);
-    }
-
-
-    /*##########################################################################
-    # Accessor
-    ##########################################################################*/
-
-    /**
-     * @return  string
-     */
-    public function getName()
-    {
-        return $this->_name;
-    }
-
-    /**
-     * @return  string
-     */
-    public function getDefault()
-    {
-        return $this->_default;
-    }
-
-    /**
-     * @return  string
-     */
-    public function getType()
-    {
-        return $this->_type;
-    }
-
-    /**
-     * @return  int
-     */
-    public function getLimit()
-    {
-        return $this->_limit;
-    }
-
-    /**
-     * @return  int
-     */
-    public function precision()
-    {
-        return $this->_precision;
-    }
-
-    /**
-     * @return  int
-     */
-    public function scale()
-    {
-        return $this->_scale;
-    }
-
-    /**
-     * @return  boolean
-     */
-    public function isNull()
-    {
-        return $this->_null;
-    }
-
-    /**
-     * @return  string
-     */
-    public function getSqlType()
-    {
-        return $this->_sqlType;
-    }
-
-
-    /*##########################################################################
-    # Type Juggling
-    ##########################################################################*/
-
-    /**
-     * Used to convert from Strings to BLOBs
-     *
-     * @return  string
-     */
-    public function stringToBinary($value)
-    {
-        return $value;
-    }
-
-    /**
-     * Used to convert from BLOBs to Strings
-     *
-     * @return  string
-     */
-    public function binaryToString($value)
-    {
-        return $value;
-    }
-
-    /**
-     * @param   string  $string
-     * @return  Horde_Date
-     */
-    public function stringToDate($string)
-    {
-        if (empty($string) ||
-            // preserve '0000-00-00' (http://bugs.php.net/bug.php?id=45647)
-            preg_replace('/[^\d]/', '', $string) == 0) {
-            return null;
-        }
-
-        $d = new Horde_Date($string);
-        $d->setDefaultFormat('Y-m-d');
-
-        return $d;
-    }
-
-    /**
-     * @param   string  $string
-     * @return  Horde_Date
-     */
-    public function stringToTime($string)
-    {
-        if (empty($string) ||
-            // preserve '0000-00-00 00:00:00' (http://bugs.php.net/bug.php?id=45647)
-            preg_replace('/[^\d]/', '', $string) == 0) {
-            return null;
-        }
-
-        return new Horde_Date($string);
-    }
-
-    /**
-     * @TODO Return a Horde_Date object instead?
-     *
-     * @param   string  $string
-     * @return  Horde_Date
-     */
-    public function stringToDummyTime($value)
-    {
-        if (empty($string)) {
-            return null;
-        }
-        return $this->stringToTime('2000-01-01 ' . $string);
-    }
-
-    /**
-     * @param   mixed  $value
-     * @return  boolean
-     */
-    public function valueToBoolean($value)
-    {
-        if ($value === true || $value === false) {
-            return $value;
-        }
-
-        $value = strtolower($value);
-        return $value == 'true' || $value == 't' || $value == '1';
-    }
-
-    /**
-     * @param   mixed  $value
-     * @return  decimal
-     */
-    public function valueToDecimal($value)
-    {
-        return (float)$value;
-    }
-
-
-    /*##########################################################################
-    # Protected
-    ##########################################################################*/
-
-    /**
-     * @param   string  $sqlType
-     * @return  int
-     */
-    protected function _extractLimit($sqlType)
-    {
-        if (preg_match("/\((.*)\)/", $sqlType, $matches)) {
-            return (int)$matches[1];
-        }
-        return null;
-    }
-
-    /**
-     * @param   string  $sqlType
-     * @return  int
-     */
-    protected function _extractPrecision($sqlType)
-    {
-        if (preg_match("/^(numeric|decimal|number)\((\d+)(,\d+)?\)/i", $sqlType, $matches)) {
-            return (int)$matches[2];
-        }
-        return null;
-    }
-
-    /**
-     * @param   string  $sqlType
-     * @return  int
-     */
-    protected function _extractScale($sqlType)
-    {
-        switch (true) {
-            case preg_match("/^(numeric|decimal|number)\((\d+)\)/i", $sqlType):
-                return 0;
-            case preg_match("/^(numeric|decimal|number)\((\d+)(,(\d+))\)/i",
-                            $sqlType, $match):
-                return (int)$match[4];
-        }
-    }
-
-    /**
-     * @param   string  $fieldType
-     * @return  string
-     */
-    protected function _simplifiedType($fieldType)
-    {
-        switch (true) {
-            case preg_match('/int/i', $fieldType):
-                return 'integer';
-            case preg_match('/float|double/i', $fieldType):
-                return 'float';
-            case preg_match('/decimal|numeric|number/i', $fieldType):
-                return $this->_scale == 0 ? 'integer' : 'decimal';
-            case preg_match('/datetime/i', $fieldType):
-                return 'datetime';
-            case preg_match('/timestamp/i', $fieldType):
-                return 'timestamp';
-            case preg_match('/time/i', $fieldType):
-                return 'time';
-            case preg_match('/date/i', $fieldType):
-                return 'date';
-            case preg_match('/clob|text/i', $fieldType):
-                return 'text';
-            case preg_match('/blob|binary/i', $fieldType):
-                return 'binary';
-            case preg_match('/char|string/i', $fieldType):
-                return 'string';
-            case preg_match('/boolean/i', $fieldType):
-                return 'boolean';
-        }
-    }
-
-}
diff --git a/framework/Db/lib/Horde/Db/Adapter/Abstract/ColumnDefinition.php b/framework/Db/lib/Horde/Db/Adapter/Abstract/ColumnDefinition.php
deleted file mode 100644 (file)
index f53b116..0000000
+++ /dev/null
@@ -1,227 +0,0 @@
-<?php
-/**
- * Copyright 2007 Maintainable Software, LLC
- * Copyright 2008-2009 The Horde Project (http://www.horde.org/)
- *
- * @author     Mike Naberezny <mike@maintainable.com>
- * @author     Derek DeVries <derek@maintainable.com>
- * @author     Chuck Hagenbuch <chuck@horde.org>
- * @license    http://opensource.org/licenses/bsd-license.php
- * @category   Horde
- * @package    Horde_Db
- * @subpackage Adapter
- */
-
-/**
- * @author     Mike Naberezny <mike@maintainable.com>
- * @author     Derek DeVries <derek@maintainable.com>
- * @author     Chuck Hagenbuch <chuck@horde.org>
- * @license    http://opensource.org/licenses/bsd-license.php
- * @category   Horde
- * @package    Horde_Db
- * @subpackage Adapter
- */
-class Horde_Db_Adapter_Abstract_ColumnDefinition
-{
-    protected $_base      = null;
-    protected $_name      = null;
-    protected $_type      = null;
-    protected $_limit     = null;
-    protected $_precision = null;
-    protected $_scale     = null;
-    protected $_default   = null;
-    protected $_null      = null;
-
-    /**
-     * Construct
-     */
-    public function __construct($base, $name, $type, $limit=null,
-         $precision=null, $scale=null, $default=null, $null=null)
-    {
-        // protected
-        $this->_base      = $base;
-
-        // public
-        $this->_name      = $name;
-        $this->_type      = $type;
-        $this->_limit     = $limit;
-        $this->_precision = $precision;
-        $this->_scale     = $scale;
-        $this->_default   = $default;
-        $this->_null      = $null;
-    }
-
-    /*##########################################################################
-    # Public
-    ##########################################################################*/
-
-    /**
-     * @return  string
-     */
-    public function toSql()
-    {
-        $sql = $this->_base->quoteColumnName($this->_name).' ';
-        try {
-            $sql .= $this->_base->typeToSql($this->_type,      $this->_limit,
-                                            $this->_precision, $this->_scale);
-        } catch (Exception $e) {
-            $sql .= $this->_type;
-        }
-        return $this->_addColumnOptions($sql, array('null'    => $this->_null,
-                                                    'default' => $this->_default));
-    }
-
-    /**
-     * @return  string
-     */
-    public function __toString()
-    {
-        return $this->toSql();
-    }
-
-
-    /*##########################################################################
-    # Accessor
-    ##########################################################################*/
-
-    /**
-     * @return  string
-     */
-    public function getName()
-    {
-        return $this->_name;
-    }
-
-    /**
-     * @return  string
-     */
-    public function getDefault()
-    {
-        return $this->_default;
-    }
-
-    /**
-     * @return  string
-     */
-    public function getType()
-    {
-        return $this->_type;
-    }
-
-    /**
-     * @return  string
-     */
-    public function getSqlType()
-    {
-        try {
-            return $this->_base->typeToSql($this->_type, $this->_limit, $this->_precision, $this->_scale);
-        } catch (Exception $e) {
-            return $this->_type;
-        }
-    }
-
-    /**
-     * @return  int
-     */
-    public function getLimit()
-    {
-        return $this->_limit;
-    }
-
-    /**
-     * @return  int
-     */
-    public function precision()
-    {
-        return $this->_precision;
-    }
-
-    /**
-     * @return  int
-     */
-    public function scale()
-    {
-        return $this->_scale;
-    }
-
-    /**
-     * @return  boolean
-     */
-    public function isNull()
-    {
-        return $this->_null;
-    }
-
-    /**
-     * @param   string
-     */
-    public function setName($name)
-    {
-        $this->_name = $name;
-    }
-
-    /**
-     * @param  string
-     */
-    public function setDefault($default)
-    {
-        $this->_default = $default;
-    }
-
-    /**
-     * @param  string
-     */
-    public function setType($type)
-    {
-        $this->_type = $type;
-    }
-
-    /**
-     * @param  int
-     */
-    public function setLimit($limit)
-    {
-        $this->_limit = $limit;
-    }
-
-    /**
-     * @param  int
-     */
-    public function setPrecision($precision)
-    {
-        $this->_precision = $precision;
-    }
-
-    /**
-     * @param  int
-     */
-    public function setScale($scale)
-    {
-        $this->_scale = $scale;
-    }
-
-    /**
-     * @param  boolean
-     */
-    public function setNull($null)
-    {
-        $this->_null = $null;
-    }
-
-
-    /*##########################################################################
-    # Schema Statements
-    ##########################################################################*/
-
-    /**
-     * @param   string  $sql
-     * @param   array   $options
-     */
-    protected function _addColumnOptions($sql, $options)
-    {
-        return $this->_base->addColumnOptions($sql,
-            array_merge($options, array('column' => $this))
-        );
-    }
-
-}
diff --git a/framework/Db/lib/Horde/Db/Adapter/Abstract/Index.php b/framework/Db/lib/Horde/Db/Adapter/Abstract/Index.php
deleted file mode 100644 (file)
index 9407b2e..0000000
+++ /dev/null
@@ -1,83 +0,0 @@
-<?php
-/**
- * Copyright 2007 Maintainable Software, LLC
- * Copyright 2008-2009 The Horde Project (http://www.horde.org/)
- *
- * @author     Mike Naberezny <mike@maintainable.com>
- * @author     Derek DeVries <derek@maintainable.com>
- * @author     Chuck Hagenbuch <chuck@horde.org>
- * @license    http://opensource.org/licenses/bsd-license.php
- * @category   Horde
- * @package    Horde_Db
- * @subpackage Adapter
- */
-
-/**
- * @author     Mike Naberezny <mike@maintainable.com>
- * @author     Derek DeVries <derek@maintainable.com>
- * @author     Chuck Hagenbuch <chuck@horde.org>
- * @license    http://opensource.org/licenses/bsd-license.php
- * @category   Horde
- * @package    Horde_Db
- * @subpackage Adapter
- */
-class Horde_Db_Adapter_Abstract_Index
-{
-    public $table;
-    public $name;
-    public $unique;
-    public $primary;
-    public $columns;
-
-
-    /*##########################################################################
-    # Construct/Destruct
-    ##########################################################################*/
-
-    /**
-     * Construct
-     *
-     * @param   string  $table    The table the index is on
-     * @param   string  $name     The index's name
-     * @param   boolean $primary  Is this a primary key?
-     * @param   boolean $unique   Is this a unique index?
-     * @param   array   $columns  The columns this index covers
-     */
-    public function __construct($table, $name, $primary, $unique, $columns)
-    {
-        $this->table   = $table;
-        $this->name    = $name;
-        $this->primary = $primary;
-        $this->unique  = $unique;
-        $this->columns = $columns;
-    }
-
-
-    /*##########################################################################
-    # Accessor
-    ##########################################################################*/
-
-    /**
-     * @return  string
-     */
-    public function getName()
-    {
-        return $this->name;
-    }
-
-
-    /*##########################################################################
-    # Casting
-    ##########################################################################*/
-
-    /**
-     * Comma-separated list of the columns in the primary key
-     *
-     * @return string
-     */
-    public function __toString()
-    {
-        return implode(',', $this->columns);
-    }
-
-}
diff --git a/framework/Db/lib/Horde/Db/Adapter/Abstract/Schema.php b/framework/Db/lib/Horde/Db/Adapter/Abstract/Schema.php
deleted file mode 100644 (file)
index 0bb5d5c..0000000
+++ /dev/null
@@ -1,749 +0,0 @@
-<?php
-/**
- * Copyright 2007 Maintainable Software, LLC
- * Copyright 2008-2009 The Horde Project (http://www.horde.org/)
- *
- * @author     Mike Naberezny <mike@maintainable.com>
- * @author     Derek DeVries <derek@maintainable.com>
- * @author     Chuck Hagenbuch <chuck@horde.org>
- * @license    http://opensource.org/licenses/bsd-license.php
- * @category   Horde
- * @package    Horde_Db
- * @subpackage Adapter
- */
-
-/**
- * @author     Mike Naberezny <mike@maintainable.com>
- * @author     Derek DeVries <derek@maintainable.com>
- * @author     Chuck Hagenbuch <chuck@horde.org>
- * @license    http://opensource.org/licenses/bsd-license.php
- * @category   Horde
- * @package    Horde_Db
- * @subpackage Adapter
- */
-abstract class Horde_Db_Adapter_Abstract_Schema
-{
-    /**
-     * @var Cache object
-     */
-    protected $_cache = null;
-
-    /**
-     * @var Logger
-     */
-    protected $_logger = null;
-
-    /**
-     * @var Horde_Db_Adapter_Abstract
-     */
-    protected $_adapter = null;
-
-    /**
-     * @var array
-     */
-    protected $_adapterMethods = array();
-
-
-    /*##########################################################################
-    # Construct/Destruct
-    ##########################################################################*/
-
-    /**
-     * @param Horde_Db_Adapter_Abstract $adapter
-     * @param array $config
-     */
-    public function __construct($adapter, $config = array())
-    {
-        $this->_adapter = $adapter;
-        $this->_adapterMethods = array_flip(get_class_methods($adapter));
-
-        $this->_cache = isset($config['cache']) ? $config['cache'] : new Horde_Support_Stub;
-        $this->_logger = isset($config['logger']) ? $config['logger'] : new Horde_Support_Stub;
-    }
-
-
-    /*##########################################################################
-    # Object composition
-    ##########################################################################*/
-
-    /**
-     * Delegate calls to the adapter object.
-     *
-     * @param  string  $method
-     * @param  array   $args
-     */
-    public function __call($method, $args)
-    {
-        if (isset($this->_adapterMethods[$method])) {
-            return call_user_func_array(array($this->_adapter, $method), $args);
-        }
-
-        throw new BadMethodCallException('Call to undeclared method "'.$method.'"');
-    }
-
-
-    /*##########################################################################
-    # Quoting
-    ##########################################################################*/
-
-    /**
-     * Quotes the column value to help prevent
-     * {SQL injection attacks}[http://en.wikipedia.org/wiki/SQL_injection].
-     *
-     * @param   string  $value
-     * @param   string  $column
-     * @return  string
-     */
-    public function quote($value, $column=null)
-    {
-        if (is_object($value) && is_callable(array($value, 'quotedId'))) {
-            return $value->quotedId();
-        }
-
-        $type = isset($column) ? $column->getType() : null;
-
-        if (is_null($value)) {
-            return 'NULL';
-        } elseif ($value === true) {
-            return $type == 'integer' ? '1' : $this->quoteTrue();
-        } elseif ($value === false) {
-            return $type == 'integer' ? '0' : $this->quoteFalse();
-        } elseif (is_int($value) || is_float($value)) {
-            return $value;
-            /*@TODO
-          else
-            if value.acts_like?(:date) || value.acts_like?(:time)
-              "'#{quoted_date(value)}'"
-            else
-              "#{quoted_string_prefix}'#{quote_string(value.to_yaml)}'"
-            end
-            */
-        } elseif ($value instanceof DateTime || $value instanceof Horde_Date) {
-            return $this->_adapter->quoteString($type == 'integer'
-                                                ? $value->format('U')
-                                                : $value->format('Y-m-d H:i:s'));
-        } else {
-            /*@TODO
-          when String, ActiveSupport::Multibyte::Chars
-            value = value.to_s
-            if column && column.type == :binary && column.class.respond_to?(:string_to_binary)
-              "#{quoted_string_prefix}'#{quote_string(column.class.string_to_binary(value))}'" # ' (for ruby-mode)
-            elsif column && [:integer, :float].include?(column.type)
-              value = column.type == :integer ? value.to_i : value.to_f
-              value.to_s
-            else
-              "#{quoted_string_prefix}'#{quote_string(value)}'" # ' (for ruby-mode)
-            end
-            */
-            return $this->_adapter->quoteString($value);
-        }
-    }
-
-    /**
-     * Quotes a string, escaping any ' (single quote) and \ (backslash)
-     * characters..
-     *
-     * @param   string  $string
-     * @return  string
-     */
-    public function quoteString($string)
-    {
-        return "'".str_replace(array('\\', '\''), array('\\\\', '\\\''), $string)."'";
-    }
-
-    /**
-     * Returns a quoted form of the column name. This is highly adapter
-     * specific.
-     *
-     * @param   string  $name
-     * @return  string
-     */
-    abstract public function quoteColumnName($name);
-
-    /**
-     * Returns a quoted form of the table name. Defaults to column name quoting.
-     *
-     * @param   string  $name
-     * @return  string
-     */
-    public function quoteTableName($name)
-    {
-        return $this->quoteColumnName($name);
-    }
-
-    /**
-     * @return  string
-     */
-    public function quoteTrue()
-    {
-        return "'t'";
-    }
-
-    /**
-     * @return  string
-     */
-    public function quoteFalse()
-    {
-        return "'f'";
-    }
-
-    /**
-     * @return  string
-     */
-    public function quoteDate($value)
-    {
-        return $this->_adapter->quoteString((string)$value);
-    }
-
-    /**
-     * @return  string
-     */
-    public function quotedStringPrefix()
-    {
-        return '';
-    }
-
-
-    /*##########################################################################
-    # Schema Statements
-    ##########################################################################*/
-
-    /**
-     * Returns a Hash of mappings from the abstract data types to the native
-     * database types.  See TableDefinition#column for details on the recognized
-     * abstract data types.
-     *
-     * @return  array
-     */
-    public function nativeDatabaseTypes()
-    {
-        return array();
-    }
-
-    /**
-     * This is the maximum length a table alias can be
-     *
-     * @return  int
-     */
-    public function tableAliasLength()
-    {
-        return 255;
-    }
-
-    /**
-     * Truncates a table alias according to the limits of the current adapter.
-     *
-     * @param   string  $tableName
-     * @return  string
-     */
-    public function tableAliasFor($tableName)
-    {
-        $alias = substr($tableName, 0, $this->tableAliasLength());
-        return str_replace('.', '_', $alias);
-    }
-
-    /**
-     * @param   string  $name
-     * @return  array
-     */
-    abstract public function tables($name = null);
-
-    /**
-     * Get a Horde_Db_Adapter_Abstract_Table object for the table.
-     *
-     * @param  string  $tableName
-     * @param  string  $name
-     *
-     * @return Horde_Db_Adapter_Abstract_Table
-     */
-    public function table($tableName, $name = null)
-    {
-        return $this->componentFactory('Table', array(
-            $tableName,
-            $this->primaryKey($tableName),
-            $this->columns($tableName, $name),
-            $this->indexes($tableName, $name),
-        ));
-    }
-
-    /**
-     * Return a table's primary key
-     */
-    abstract public function primaryKey($tableName, $name = null);
-
-    /**
-     * Returns an array of indexes for the given table.
-     *
-     * @param   string  $tableName
-     * @param   string  $name
-     * @return  array
-     */
-    abstract public function indexes($tableName, $name = null);
-
-    /**
-     * Returns an array of Horde_Db_Adapter_Abstract_Column objects for the
-     * table specified by +table_name+.  See the concrete implementation for
-     * details on the expected parameter values.
-     *
-     * @param   string  $tableName
-     * @param   string  $name
-     * @return  array
-     */
-    abstract public function columns($tableName, $name = null);
-
-    /**
-     * Creates a new table
-     * There are two ways to work with #create_table.  You can use the block
-     * form or the regular form, like this:
-     *
-     * === Block form
-     *  # create_table() yields a TableDefinition instance
-     *  create_table(:suppliers) do |t|
-     *    t.column :name, :string, :limit => 60
-     *    # Other fields here
-     *  end
-     *
-     * === Regular form
-     *  create_table(:suppliers)
-     *  add_column(:suppliers, :name, :string, {:limit => 60})
-     *
-     * The +options+ hash can include the following keys:
-     * [<tt>:id</tt>]
-     *   Set to true or false to add/not add a primary key column
-     *   automatically.  Defaults to true.
-     * [<tt>:primary_key</tt>]
-     *   The name of the primary key, if one is to be added automatically.
-     *   Defaults to +id+.
-     * [<tt>:options</tt>]
-     *   Any extra options you want appended to the table definition.
-     * [<tt>:temporary</tt>]
-     *   Make a temporary table.
-     * [<tt>:force</tt>]
-     *   Set to true or false to drop the table before creating it.
-     *   Defaults to false.
-     *
-     * ===== Examples
-     * ====== Add a backend specific option to the generated SQL (MySQL)
-     *  create_table(:suppliers, :options => 'ENGINE=InnoDB DEFAULT CHARSET=utf8')
-     * generates:
-     *  CREATE TABLE suppliers (
-     *    id int(11) DEFAULT NULL auto_increment PRIMARY KEY
-     *  ) ENGINE=InnoDB DEFAULT CHARSET=utf8
-     *
-     * ====== Rename the primary key column
-     *  create_table(:objects, :primary_key => 'guid') do |t|
-     *    t.column :name, :string, :limit => 80
-     *  end
-     * generates:
-     *  CREATE TABLE objects (
-     *    guid int(11) DEFAULT NULL auto_increment PRIMARY KEY,
-     *    name varchar(80)
-     *  )
-     *
-     * ====== Do not add a primary key column
-     *  create_table(:categories_suppliers, :id => false) do |t|
-     *    t.column :category_id, :integer
-     *    t.column :supplier_id, :integer
-     *  end
-     * generates:
-     *  CREATE TABLE categories_suppliers_join (
-     *    category_id int,
-     *    supplier_id int
-     *  )
-     *
-     * See also TableDefinition#column for details on how to create columns.
-     *
-     * @param   string  $name
-     * @param   array   $options
-     */
-    public function createTable($name, $options=array())
-    {
-        $pk = isset($options['primaryKey']) && $options['primaryKey'] === false ? false : 'id';
-        $tableDefinition =
-            $this->componentFactory('TableDefinition', array($name, $this, $options));
-        if ($pk != false) {
-            $tableDefinition->primaryKey($pk);
-        }
-        return $tableDefinition;
-    }
-
-    /**
-     * Execute table creation
-     *
-     * @param   string  $name
-     * @param   array   $options
-     */
-    public function endTable($name, $options=array())
-    {
-        if ($name instanceof Horde_Db_Adapter_Abstract_TableDefinition) {
-            $tableDefinition = $name;
-            $options = array_merge($tableDefinition->getOptions(), $options);
-        } else {
-            $tableDefinition = $this->createTable($name, $options);
-        }
-
-        // drop previous
-        if (isset($options['force'])) {
-            $this->dropTable($tableDefinition->getName(), $options);
-        }
-
-        $temp = !empty($options['temporary']) ? 'TEMPORARY'           : null;
-        $opts = !empty($options['options'])   ? $options['options']   : null;
-
-        $sql  = "CREATE $temp TABLE ".$this->quoteTableName($tableDefinition->getName())." (\n".
-                  $tableDefinition->toSql()."\n".
-                ") $opts";
-        return $this->execute($sql);
-    }
-
-    /**
-     * Renames a table.
-     * ===== Example
-     *  rename_table('octopuses', 'octopi')
-     *
-     * @param   string  $name
-     * @param   string  $newName
-     */
-    abstract public function renameTable($name, $newName);
-
-    /**
-     * Drops a table from the database.
-     *
-     * @param   string  $name
-     */
-    public function dropTable($name)
-    {
-        $this->_clearTableCache($name);
-        return $this->execute('DROP TABLE ' . $this->quoteTableName($name));
-    }
-
-    /**
-     * Adds a new column to the named table.
-     * See TableDefinition#column for details of the options you can use.
-     *
-     * @param   string  $tableName
-     * @param   string  $columnName
-     * @param   string  $type
-     * @param   array   $options
-     */
-    public function addColumn($tableName, $columnName, $type, $options=array())
-    {
-        $this->_clearTableCache($tableName);
-
-        $limit     = isset($options['limit'])     ? $options['limit']     : null;
-        $precision = isset($options['precision']) ? $options['precision'] : null;
-        $scale     = isset($options['scale'])     ? $options['scale']     : null;
-
-        $sql = 'ALTER TABLE ' . $this->quoteTableName($tableName) .
-            ' ADD '.$this->quoteColumnName($columnName) .
-            ' '.$this->typeToSql($type, $limit, $precision, $scale);
-        $sql = $this->addColumnOptions($sql, $options);
-        return $this->execute($sql);
-    }
-
-    /**
-     * Removes the column from the table definition.
-     * ===== Examples
-     *  remove_column(:suppliers, :qualification)
-     *
-     * @param   string  $tableName
-     * @param   string  $columnName
-     */
-    public function removeColumn($tableName, $columnName)
-    {
-        $this->_clearTableCache($tableName);
-
-        $sql = 'ALTER TABLE ' . $this->quoteTableName($tableName).' DROP '.$this->quoteColumnName($columnName);
-        return $this->execute($sql);
-    }
-
-    /**
-     * Changes the column's definition according to the new options.
-     * See TableDefinition#column for details of the options you can use.
-     * ===== Examples
-     *  change_column(:suppliers, :name, :string, :limit => 80)
-     *  change_column(:accounts, :description, :text)
-     *
-     * @param   string  $tableName
-     * @param   string  $columnName
-     * @param   string  $type
-     * @param   array   $options
-     */
-    abstract public function changeColumn($tableName, $columnName, $type, $options=array());
-
-    /**
-     * Sets a new default value for a column.  If you want to set the default
-     * value to +NULL+, you are out of luck.  You need to
-     * DatabaseStatements#execute the apppropriate SQL statement yourself.
-     * ===== Examples
-     *  change_column_default(:suppliers, :qualification, 'new')
-     *  change_column_default(:accounts, :authorized, 1)
-     *
-     * @param   string  $tableName
-     * @param   string  $columnName
-     * @param   string  $default
-     */
-    abstract public function changeColumnDefault($tableName, $columnName, $default);
-
-    /**
-     * Renames a column.
-     * ===== Example
-     *  rename_column(:suppliers, :description, :name)
-     *
-     * @param   string  $tableName
-     * @param   string  $columnName
-     * @param   string  $newColumnName
-     */
-    abstract public function renameColumn($tableName, $columnName, $newColumnName);
-
-    /**
-     * Adds a new index to the table.  +column_name+ can be a single Symbol, or
-     * an Array of Symbols.
-     *
-     * The index will be named after the table and the first column names,
-     * unless you pass +:name+ as an option.
-     *
-     * When creating an index on multiple columns, the first column is used as a name
-     * for the index. For example, when you specify an index on two columns
-     * [+:first+, +:last+], the DBMS creates an index for both columns as well as an
-     * index for the first colum +:first+. Using just the first name for this index
-     * makes sense, because you will never have to create a singular index with this
-     * name.
-     *
-     * ===== Examples
-     * ====== Creating a simple index
-     *  add_index(:suppliers, :name)
-     * generates
-     *  CREATE INDEX suppliers_name_index ON suppliers(name)
-     *
-     * ====== Creating a unique index
-     *  add_index(:accounts, [:branch_id, :party_id], :unique => true)
-     * generates
-     *  CREATE UNIQUE INDEX accounts_branch_id_index ON accounts(branch_id, party_id)
-     *
-     * ====== Creating a named index
-     *  add_index(:accounts, [:branch_id, :party_id], :unique => true, :name => 'by_branch_party')
-     * generates
-     *  CREATE UNIQUE INDEX by_branch_party ON accounts(branch_id, party_id)
-     *
-     * @param   string  $tableName
-     * @param   string  $columnName
-     * @param   array   $options
-     */
-    public function addIndex($tableName, $columnName, $options=array())
-    {
-        $this->_clearTableCache($tableName);
-
-        $columnNames = (array)($columnName);
-        $indexName = $this->indexName($tableName, array('column' => $columnNames));
-
-        $indexType = !empty($options['unique']) ? "UNIQUE"         : null;
-        $indexName = !empty($options['name'])   ? $options['name'] : $indexName;
-
-        foreach ($columnNames as $colName) {
-            $quotedCols[] = $this->quoteColumnName($colName);
-        }
-        $quotedColumnNames = implode(', ', $quotedCols);
-        $sql = "CREATE $indexType INDEX ".$this->quoteColumnName($indexName).
-            'ON '.$this->quoteTableName($tableName) . " ($quotedColumnNames)";
-        return $this->execute($sql);
-    }
-
-    /**
-     * Remove the given index from the table.
-     *
-     * Remove the suppliers_name_index in the suppliers table (legacy support, use the second or third forms).
-     *   remove_index :suppliers, :name
-     * Remove the index named accounts_branch_id in the accounts table.
-     *   remove_index :accounts, :column => :branch_id
-     * Remove the index named by_branch_party in the accounts table.
-     *   remove_index :accounts, :name => :by_branch_party
-     *
-     * You can remove an index on multiple columns by specifying the first column.
-     *   add_index :accounts, [:username, :password]
-     *   remove_index :accounts, :username
-     *
-     * @param   string  $tableName
-     * @param   array   $options
-     */
-    public function removeIndex($tableName, $options=array())
-    {
-        $this->_clearTableCache($tableName);
-
-        $index = $this->indexName($tableName, $options);
-        $sql = "DROP INDEX ".$this->quoteColumnName($index).' ON ' . $this->quoteTableName($tableName);
-        return $this->execute($sql);
-    }
-
-    /**
-     * Get the name of the index
-     *
-     * @param   string  $tableName
-     * @param   array   $options
-     */
-    public function indexName($tableName, $options=array())
-    {
-        if (!is_array($options)) {
-            $options = array('column' => $options);
-        }
-
-        if (isset($options['column'])) {
-            $columns = (array)$options['column'];
-            return "index_{$tableName}_on_".implode('_and_', $columns);
-
-        } elseif (isset($options['name'])) {
-            return $options['name'];
-
-        } else {
-            throw new Horde_Db_Exception('You must specify the index name');
-        }
-    }
-
-    /**
-     * Returns a string of <tt>CREATE TABLE</tt> SQL statement(s) for recreating the
-     * entire structure of the database.
-     *
-     * @param   string  $table
-     * @return  string
-     */
-    abstract public function structureDump($table = null);
-
-    /**
-     * Recreate the given db
-     *
-     * @param   string  $name
-     */
-    public function recreateDatabase($name)
-    {
-        $this->dropDatabase($name);
-        return $this->createDatabase($name);
-    }
-
-    /**
-     * Create the given db
-     *
-     * @param   string  $name
-     */
-    abstract public function createDatabase($name);
-
-    /**
-     * Drop the given db
-     *
-     * @param   string  $name
-     */
-    abstract public function dropDatabase($name);
-
-    /**
-     * Get the name of the current db
-     *
-     * @return  string
-     */
-    abstract public function currentDatabase();
-
-    /**
-     * Should not be called normally, but this operation is non-destructive.
-     * The migrations module handles this automatically.
-     */
-    public function initializeSchemaInformation()
-    {
-        try {
-            $this->execute("CREATE TABLE schema_info (".
-                           "  version ".$this->typeToSql('integer').
-                           ")");
-            return $this->execute("INSERT INTO schema_info (version) VALUES (0)");
-        } catch (Exception $e) {}
-    }
-
-    /**
-     * The sql for this column type
-     *
-     * @param   string  $type
-     * @param   string  $limit
-     */
-    public function typeToSql($type, $limit=null, $precision=null, $scale=null)
-    {
-        $natives = $this->nativeDatabaseTypes();
-        $native = isset($natives[$type]) ? $natives[$type] : null;
-        if (empty($native)) { return $type; }
-
-        $sql = is_array($native) ? $native['name'] : $native;
-        if ($type == 'decimal') {
-            $nativePrec  = isset($native['precision']) ? $native['precision'] : null;
-            $nativeScale = isset($native['scale'])     ? $native['scale']     : null;
-
-            $precision = !empty($precision) ? $precision : $nativePrec;
-            $scale     = !empty($scale)     ? $scale     : $nativeScale;
-            if ($precision) {
-                $sql .= $scale ? "($precision, $scale)" : "($precision)";
-            }
-        } else {
-            $nativeLimit = is_array($native) ? $native['limit'] : null;
-            if ($limit = !empty($limit) ? $limit : $nativeLimit) {
-                $sql .= "($limit)";
-            }
-        }
-        return $sql;
-    }
-
-    /**
-     * Add default/null options to column sql
-     *
-     * @param   string  $sql
-     * @param   array   $options
-     */
-    public function addColumnOptions($sql, $options)
-    {
-        if (isset($options['null']) && $options['null'] === false) {
-            $sql .= ' NOT NULL';
-        }
-        if (isset($options['default'])) {
-            $default = $options['default'];
-            $column  = isset($options['column'])  ? $options['column']  : null;
-            $sql .= ' DEFAULT '.$this->quote($default, $column);
-        }
-        return $sql;
-    }
-
-    /**
-     * SELECT DISTINCT clause for a given set of columns and a given
-     * ORDER BY clause. Both PostgreSQL and Oracle override this for
-     * custom DISTINCT syntax.
-     *
-     * $connection->distinct("posts.id", "posts.created_at desc")
-     *
-     * @param   string  $columns
-     * @param   string  $orderBy
-     */
-    public function distinct($columns, $orderBy=null)
-    {
-        return "DISTINCT $columns";
-    }
-
-    /**
-     * ORDER BY clause for the passed order option.
-     * PostgreSQL overrides this due to its stricter standards compliance.
-     *
-     * @param   string  $sql
-     * @param   array   $options
-     * @return  string
-     */
-    public function addOrderByForAssocLimiting($sql, $options)
-    {
-        return $sql.'ORDER BY '.$options['order'];
-    }
-
-
-    /*##########################################################################
-    # Protected
-    ##########################################################################*/
-
-    /**
-     * We need to clear cache for tables when altering them at all
-     */
-    protected function _clearTableCache($tableName)
-    {
-        $this->_cache->set("tables/columns/$tableName", null);
-        $this->_cache->set("tables/indexes/$tableName", null);
-    }
-
-}
diff --git a/framework/Db/lib/Horde/Db/Adapter/Abstract/Table.php b/framework/Db/lib/Horde/Db/Adapter/Abstract/Table.php
deleted file mode 100644 (file)
index 177c358..0000000
+++ /dev/null
@@ -1,123 +0,0 @@
-<?php
-/**
- * Copyright 2007 Maintainable Software, LLC
- * Copyright 2008 The Horde Project (http://www.horde.org/)
- *
- * @author     Mike Naberezny <mike@maintainable.com>
- * @author     Derek DeVries <derek@maintainable.com>
- * @author     Chuck Hagenbuch <chuck@horde.org>
- * @license    http://opensource.org/licenses/bsd-license.php
- * @category   Horde
- * @package    Horde_Db
- * @subpackage Adapter
- */
-
-/**
- * @author     Mike Naberezny <mike@maintainable.com>
- * @author     Derek DeVries <derek@maintainable.com>
- * @author     Chuck Hagenbuch <chuck@horde.org>
- * @license    http://opensource.org/licenses/bsd-license.php
- * @category   Horde
- * @package    Horde_Db
- * @subpackage Adapter
- */
-class Horde_Db_Adapter_Abstract_Table
-{
-    protected $_name;
-    protected $_primaryKey;
-    protected $_columns;
-    protected $_indexes;
-
-
-    /*##########################################################################
-    # Construct/Destruct
-    ##########################################################################*/
-
-    /**
-     * Construct
-     *
-     * @param   string  $name     The table's name, such as <tt>supplier_id</tt> in <tt>supplier_id int(11)</tt>.
-     */
-    public function __construct($name, $primaryKey, $columns, $indexes)
-    {
-        $this->_name       = $name;
-        $this->_primaryKey = $primaryKey;
-        $this->_columns    = $columns;
-        $this->_indexes    = $indexes;
-    }
-
-
-    /*##########################################################################
-    # Accessor
-    ##########################################################################*/
-
-    /**
-     * @return  string
-     */
-    public function getName()
-    {
-        return $this->_name;
-    }
-
-    /**
-     * @return  mixed
-     */
-    public function getPrimaryKey()
-    {
-        return $this->_primaryKey;
-    }
-
-    /**
-     * @return  array
-     */
-    public function getColumns()
-    {
-        return $this->_columns;
-    }
-
-    /**
-     * @return  Horde_Db_Adapter_Abstract_Column
-     */
-    public function getColumn($column)
-    {
-        return isset($this->_columns[$column]) ? $this->_columns[$column] : null;
-    }
-
-    /**
-     * @return  array
-     */
-    public function getColumnNames()
-    {
-        $names = array();
-        foreach ($this->_columns as $column) {
-            $names[] = $column->getName();
-        }
-        return $names;
-    }
-
-    /**
-     * @return  array
-     */
-    public function getIndexes()
-    {
-        return $this->_indexes;
-    }
-
-    /**
-     * @return  array
-     */
-    public function getIndexNames()
-    {
-        $names = array();
-        foreach ($this->_indexes as $index) {
-            $names[] = $index->getName();
-        }
-        return $names;
-    }
-
-
-    /*##########################################################################
-    # Protected
-    ##########################################################################*/
-
-}
diff --git a/framework/Db/lib/Horde/Db/Adapter/Abstract/TableDefinition.php b/framework/Db/lib/Horde/Db/Adapter/Abstract/TableDefinition.php
deleted file mode 100644 (file)
index 0eff9fa..0000000
+++ /dev/null
@@ -1,235 +0,0 @@
-<?php
-/**
- * Copyright 2007 Maintainable Software, LLC
- * Copyright 2008-2009 The Horde Project (http://www.horde.org/)
- *
- * @author     Mike Naberezny <mike@maintainable.com>
- * @author     Derek DeVries <derek@maintainable.com>
- * @author     Chuck Hagenbuch <chuck@horde.org>
- * @license    http://opensource.org/licenses/bsd-license.php
- * @category   Horde
- * @package    Horde_Db
- * @subpackage Adapter
- */
-
-/**
- * @author     Mike Naberezny <mike@maintainable.com>
- * @author     Derek DeVries <derek@maintainable.com>
- * @author     Chuck Hagenbuch <chuck@horde.org>
- * @license    http://opensource.org/licenses/bsd-license.php
- * @category   Horde
- * @package    Horde_Db
- * @subpackage Adapter
- */
-class Horde_Db_Adapter_Abstract_TableDefinition implements ArrayAccess
-{
-    protected $_name    = null;
-    protected $_base    = null;
-    protected $_options = null;
-    protected $_columns = null;
-
-    /**
-     * Class Constructor
-     *
-     * @param  string  $name
-     * @param  Horde_Db_Adapter_Abstract_Schema  $base
-     * @param  array   $options
-     */
-    public function __construct($name, $base, $options=array())
-    {
-        $this->_name    = $name;
-        $this->_base    = $base;
-        $this->_options = $options;
-        $this->_columns = array();
-    }
-
-    /**
-     * @return  string
-     */
-    public function getName()
-    {
-        return $this->_name;
-    }
-
-    /**
-     * @return  array
-     */
-    public function getOptions()
-    {
-        return $this->_options;
-    }
-
-    /**
-     * @param   string  $name
-     */
-    public function primaryKey($name)
-    {
-        $natives = $this->_native();
-        $this->column($name, $natives['primaryKey']);
-    }
-
-    /**
-     * Instantiates a new column for the table.
-     * The +type+ parameter must be one of the following values:
-     * <tt>:primary_key</tt>, <tt>:string</tt>, <tt>:text</tt>,
-     * <tt>:integer</tt>, <tt>:float</tt>, <tt>:datetime</tt>,
-     * <tt>:timestamp</tt>, <tt>:time</tt>, <tt>:date</tt>,
-     * <tt>:binary</tt>, <tt>:boolean</tt>.
-     *
-     * Available options are (none of these exists by default):
-     * * <tt>:limit</tt>:
-     *   Requests a maximum column length (<tt>:string</tt>, <tt>:text</tt>,
-     *   <tt>:binary</tt> or <tt>:integer</tt> columns only)
-     * * <tt>:default</tt>:
-     *   The column's default value.  You cannot explicitely set the default
-     *   value to +NULL+.  Simply leave off this option if you want a +NULL+
-     *   default value.
-     * * <tt>:null</tt>:
-     *   Allows or disallows +NULL+ values in the column.  This option could
-     *   have been named <tt>:null_allowed</tt>.
-     *
-     * This method returns <tt>self</tt>.
-     *
-     * ===== Examples
-     *  # Assuming def is an instance of TableDefinition
-     *  def.column(:granted, :boolean)
-     *    #=> granted BOOLEAN
-     *
-     *  def.column(:picture, :binary, :limit => 2.megabytes)
-     *    #=> picture BLOB(2097152)
-     *
-     *  def.column(:sales_stage, :string, :limit => 20, :default => 'new', :null => false)
-     *    #=> sales_stage VARCHAR(20) DEFAULT 'new' NOT NULL
-     *
-     * @return  TableDefinition
-     */
-    public function column($name, $type, $options=array())
-    {
-        if ($this[$name]) {
-            $column = $this[$name];
-        } else {
-            $column = $this->_base->componentFactory('ColumnDefinition', array(
-                $this->_base, $name, $type));
-        }
-
-        $natives = $this->_native();
-        $opt = $options;
-
-        if (isset($opt['limit']) || isset($natives[$type])) {
-            $nativeLimit = isset($natives[$type]['limit']) ? $natives[$type]['limit'] : null;
-            $column->setLimit(isset($opt['limit']) ? $opt['limit'] : $nativeLimit);
-        }
-
-        $column->setPrecision(isset($opt['precision']) ? $opt['precision'] : null);
-        $column->setScale(isset($opt['scale'])         ? $opt['scale']     : null);
-        $column->setDefault(isset($opt['default'])     ? $opt['default']   : null);
-        $column->setNull(isset($opt['null'])           ? $opt['null']      : null);
-
-        $this[$name] ? $this[$name] = $column : $this->_columns[] = $column;
-        return $this;
-    }
-
-    /**
-     * Wrap up table creation block & create the table
-     */
-    public function end()
-    {
-        return $this->_base->endTable($this);
-    }
-
-    /**
-     * Returns a String whose contents are the column definitions
-     * concatenated together.  This string can then be pre and appended to
-     * to generate the final SQL to create the table.
-     *
-     * @return  string
-     */
-    public function toSql()
-    {
-        $cols = array();
-        foreach ($this->_columns as $col) { $cols[] = $col->toSql(); }
-
-        return "  ".implode(", \n  ", $cols);
-    }
-
-
-    /*##########################################################################
-    # ArrayAccess
-    ##########################################################################*/
-
-    /**
-     * ArrayAccess: Check if the given offset exists
-     *
-     * @param   int     $offset
-     * @return  boolean
-     */
-    public function offsetExists($offset)
-    {
-        foreach ($this->_columns as $column) {
-            if ($column->getName() == $offset) return true;
-        }
-        return false;
-    }
-
-    /**
-     * ArrayAccess: Return the value for the given offset.
-     *
-     * @param   int     $offset
-     * @return  object  {@link {@Horde_Db_Adapter_Abstract_ColumnDefinition}
-     */
-    public function offsetGet($offset)
-    {
-        if (!$this->offsetExists($offset)) {
-            return null;
-        }
-
-        foreach ($this->_columns as $column) {
-            if ($column->getName() == $offset) {
-                return $column;
-            }
-        }
-    }
-
-    /**
-     * ArrayAccess: Set value for given offset
-     *
-     * @param   int     $offset
-     * @param   mixed   $value
-     */
-    public function offsetSet($offset, $value)
-    {
-        foreach ($this->_columns as $key=>$column) {
-            if ($column->getName() == $offset) {
-                $this->_columns[$key] = $value;
-            }
-        }
-    }
-
-    /**
-     * ArrayAccess: remove element
-     *
-     * @param   int     $offset
-     */
-    public function offsetUnset($offset)
-    {
-        foreach ($this->_columns as $key=>$column) {
-            if ($column->getName() == $offset) {
-                unset($this->_columns[$key]);
-            }
-        }
-    }
-
-
-    /*##########################################################################
-    # Protected
-    ##########################################################################*/
-
-    /**
-     * Get the types
-     */
-    protected function _native()
-    {
-        return $this->_base->nativeDatabaseTypes();
-    }
-
-}
index bdd6f1e..1d05a68 100644 (file)
@@ -65,7 +65,7 @@ abstract class Horde_Db_Adapter_Base
     protected $_logger = null;
 
     /**
-     * @var Horde_Db_Adapter_Abstract_Schema
+     * @var Horde_Db_Adapter_Base_Schema
      */
     protected $_schema = null;
 
@@ -154,7 +154,7 @@ abstract class Horde_Db_Adapter_Base
         if (class_exists($class)) {
             $class = new ReflectionClass($class);
         } else {
-            $class = new ReflectionClass('Horde_Db_Adapter_Abstract_' . $component);
+            $class = new ReflectionClass('Horde_Db_Adapter_Base_' . $component);
         }
 
         return $class->newInstanceArgs($args);
@@ -193,7 +193,7 @@ abstract class Horde_Db_Adapter_Base
      */
     public function adapterName()
     {
-        return 'Abstract';
+        return 'Base';
     }
 
     /**
diff --git a/framework/Db/lib/Horde/Db/Adapter/Base/Column.php b/framework/Db/lib/Horde/Db/Adapter/Base/Column.php
new file mode 100644 (file)
index 0000000..f2f0c51
--- /dev/null
@@ -0,0 +1,359 @@
+<?php
+/**
+ * Copyright 2007 Maintainable Software, LLC
+ * Copyright 2008-2009 The Horde Project (http://www.horde.org/)
+ *
+ * @author     Mike Naberezny <mike@maintainable.com>
+ * @author     Derek DeVries <derek@maintainable.com>
+ * @author     Chuck Hagenbuch <chuck@horde.org>
+ * @license    http://opensource.org/licenses/bsd-license.php
+ * @category   Horde
+ * @package    Horde_Db
+ * @subpackage Adapter
+ */
+
+/**
+ * @author     Mike Naberezny <mike@maintainable.com>
+ * @author     Derek DeVries <derek@maintainable.com>
+ * @author     Chuck Hagenbuch <chuck@horde.org>
+ * @license    http://opensource.org/licenses/bsd-license.php
+ * @category   Horde
+ * @package    Horde_Db
+ * @subpackage Adapter
+ */
+class Horde_Db_Adapter_Base_Column
+{
+    protected $_name;
+    protected $_type;
+    protected $_null;
+    protected $_limit;
+    protected $_precision;
+    protected $_scale;
+    protected $_default;
+    protected $_sqlType;
+    protected $_isText;
+    protected $_isNumber;
+
+
+    /*##########################################################################
+    # Construct/Destruct
+    ##########################################################################*/
+
+    /**
+     * Construct
+     *
+     * @param   string  $name     The column's name, such as <tt>supplier_id</tt> in <tt>supplier_id int(11)</tt>.
+     * @param   string  $default  The type-casted default value, such as +new+ in <tt>sales_stage varchar(20) default 'new'</tt>.
+     * @param   string  $sqlType  Only used to extract the column's length, if necessary. For example +60+ in <tt>company_name varchar(60)</tt>.
+     * @param   boolean $null     Determines if this column allows +NULL+ values.
+     */
+    public function __construct($name, $default, $sqlType = null, $null = true)
+    {
+        $this->_name      = $name;
+        $this->_sqlType   = $sqlType;
+        $this->_null      = $null;
+        $this->_limit     = $this->_extractLimit($sqlType);
+        $this->_precision = $this->_extractPrecision($sqlType);
+        $this->_scale     = $this->_extractScale($sqlType);
+        $this->_type      = $this->_simplifiedType($sqlType);
+        $this->_default   = $this->extractDefault($default);
+
+        $this->_isText    = $this->_type == 'text'  || $this->_type == 'string';
+        $this->_isNumber  = $this->_type == 'float' || $this->_type == 'integer' || $this->_type == 'decimal';
+    }
+
+    /**
+     * @return  boolean
+     */
+    public function isText()
+    {
+        return $this->_isText;
+    }
+
+    /**
+     * @return  boolean
+     */
+    public function isNumber()
+    {
+        return $this->_isNumber;
+    }
+
+    /**
+     * Casts value (which is a String) to an appropriate instance.
+     */
+    public function typeCast($value)
+    {
+        if ($value === null) return null;
+
+        switch ($this->_type) {
+        case 'string':
+        case 'text':
+            return $value;
+        case 'integer':
+            return strlen($value) ? (int)$value : null;
+        case 'float':
+            return strlen($value) ? (float)$value : null;
+        case 'decimal':
+            return $this->valueToDecimal($value);
+        case 'datetime':
+        case 'timestamp':
+            return $this->stringToTime($value);
+        case 'time':
+            return $this->stringToDummyTime($value);
+        case 'date':
+            return $this->stringToDate($value);
+        case 'binary':
+            return $this->binaryToString($value);
+        case 'boolean':
+            return $this->valueToBoolean($value);
+        default:
+            return $value;
+        }
+    }
+
+    public function extractDefault($default)
+    {
+        return $this->typeCast($default);
+    }
+
+
+    /*##########################################################################
+    # Accessor
+    ##########################################################################*/
+
+    /**
+     * @return  string
+     */
+    public function getName()
+    {
+        return $this->_name;
+    }
+
+    /**
+     * @return  string
+     */
+    public function getDefault()
+    {
+        return $this->_default;
+    }
+
+    /**
+     * @return  string
+     */
+    public function getType()
+    {
+        return $this->_type;
+    }
+
+    /**
+     * @return  int
+     */
+    public function getLimit()
+    {
+        return $this->_limit;
+    }
+
+    /**
+     * @return  int
+     */
+    public function precision()
+    {
+        return $this->_precision;
+    }
+
+    /**
+     * @return  int
+     */
+    public function scale()
+    {
+        return $this->_scale;
+    }
+
+    /**
+     * @return  boolean
+     */
+    public function isNull()
+    {
+        return $this->_null;
+    }
+
+    /**
+     * @return  string
+     */
+    public function getSqlType()
+    {
+        return $this->_sqlType;
+    }
+
+
+    /*##########################################################################
+    # Type Juggling
+    ##########################################################################*/
+
+    /**
+     * Used to convert from Strings to BLOBs
+     *
+     * @return  string
+     */
+    public function stringToBinary($value)
+    {
+        return $value;
+    }
+
+    /**
+     * Used to convert from BLOBs to Strings
+     *
+     * @return  string
+     */
+    public function binaryToString($value)
+    {
+        return $value;
+    }
+
+    /**
+     * @param   string  $string
+     * @return  Horde_Date
+     */
+    public function stringToDate($string)
+    {
+        if (empty($string) ||
+            // preserve '0000-00-00' (http://bugs.php.net/bug.php?id=45647)
+            preg_replace('/[^\d]/', '', $string) == 0) {
+            return null;
+        }
+
+        $d = new Horde_Date($string);
+        $d->setDefaultFormat('Y-m-d');
+
+        return $d;
+    }
+
+    /**
+     * @param   string  $string
+     * @return  Horde_Date
+     */
+    public function stringToTime($string)
+    {
+        if (empty($string) ||
+            // preserve '0000-00-00 00:00:00' (http://bugs.php.net/bug.php?id=45647)
+            preg_replace('/[^\d]/', '', $string) == 0) {
+            return null;
+        }
+
+        return new Horde_Date($string);
+    }
+
+    /**
+     * @TODO Return a Horde_Date object instead?
+     *
+     * @param   string  $string
+     * @return  Horde_Date
+     */
+    public function stringToDummyTime($value)
+    {
+        if (empty($string)) {
+            return null;
+        }
+        return $this->stringToTime('2000-01-01 ' . $string);
+    }
+
+    /**
+     * @param   mixed  $value
+     * @return  boolean
+     */
+    public function valueToBoolean($value)
+    {
+        if ($value === true || $value === false) {
+            return $value;
+        }
+
+        $value = strtolower($value);
+        return $value == 'true' || $value == 't' || $value == '1';
+    }
+
+    /**
+     * @param   mixed  $value
+     * @return  decimal
+     */
+    public function valueToDecimal($value)
+    {
+        return (float)$value;
+    }
+
+
+    /*##########################################################################
+    # Protected
+    ##########################################################################*/
+
+    /**
+     * @param   string  $sqlType
+     * @return  int
+     */
+    protected function _extractLimit($sqlType)
+    {
+        if (preg_match("/\((.*)\)/", $sqlType, $matches)) {
+            return (int)$matches[1];
+        }
+        return null;
+    }
+
+    /**
+     * @param   string  $sqlType
+     * @return  int
+     */
+    protected function _extractPrecision($sqlType)
+    {
+        if (preg_match("/^(numeric|decimal|number)\((\d+)(,\d+)?\)/i", $sqlType, $matches)) {
+            return (int)$matches[2];
+        }
+        return null;
+    }
+
+    /**
+     * @param   string  $sqlType
+     * @return  int
+     */
+    protected function _extractScale($sqlType)
+    {
+        switch (true) {
+            case preg_match("/^(numeric|decimal|number)\((\d+)\)/i", $sqlType):
+                return 0;
+            case preg_match("/^(numeric|decimal|number)\((\d+)(,(\d+))\)/i",
+                            $sqlType, $match):
+                return (int)$match[4];
+        }
+    }
+
+    /**
+     * @param   string  $fieldType
+     * @return  string
+     */
+    protected function _simplifiedType($fieldType)
+    {
+        switch (true) {
+            case preg_match('/int/i', $fieldType):
+                return 'integer';
+            case preg_match('/float|double/i', $fieldType):
+                return 'float';
+            case preg_match('/decimal|numeric|number/i', $fieldType):
+                return $this->_scale == 0 ? 'integer' : 'decimal';
+            case preg_match('/datetime/i', $fieldType):
+                return 'datetime';
+            case preg_match('/timestamp/i', $fieldType):
+                return 'timestamp';
+            case preg_match('/time/i', $fieldType):
+                return 'time';
+            case preg_match('/date/i', $fieldType):
+                return 'date';
+            case preg_match('/clob|text/i', $fieldType):
+                return 'text';
+            case preg_match('/blob|binary/i', $fieldType):
+                return 'binary';
+            case preg_match('/char|string/i', $fieldType):
+                return 'string';
+            case preg_match('/boolean/i', $fieldType):
+                return 'boolean';
+        }
+    }
+
+}
diff --git a/framework/Db/lib/Horde/Db/Adapter/Base/ColumnDefinition.php b/framework/Db/lib/Horde/Db/Adapter/Base/ColumnDefinition.php
new file mode 100644 (file)
index 0000000..c8f493d
--- /dev/null
@@ -0,0 +1,227 @@
+<?php
+/**
+ * Copyright 2007 Maintainable Software, LLC
+ * Copyright 2008-2009 The Horde Project (http://www.horde.org/)
+ *
+ * @author     Mike Naberezny <mike@maintainable.com>
+ * @author     Derek DeVries <derek@maintainable.com>
+ * @author     Chuck Hagenbuch <chuck@horde.org>
+ * @license    http://opensource.org/licenses/bsd-license.php
+ * @category   Horde
+ * @package    Horde_Db
+ * @subpackage Adapter
+ */
+
+/**
+ * @author     Mike Naberezny <mike@maintainable.com>
+ * @author     Derek DeVries <derek@maintainable.com>
+ * @author     Chuck Hagenbuch <chuck@horde.org>
+ * @license    http://opensource.org/licenses/bsd-license.php
+ * @category   Horde
+ * @package    Horde_Db
+ * @subpackage Adapter
+ */
+class Horde_Db_Adapter_Base_ColumnDefinition
+{
+    protected $_base      = null;
+    protected $_name      = null;
+    protected $_type      = null;
+    protected $_limit     = null;
+    protected $_precision = null;
+    protected $_scale     = null;
+    protected $_default   = null;
+    protected $_null      = null;
+
+    /**
+     * Construct
+     */
+    public function __construct($base, $name, $type, $limit=null,
+         $precision=null, $scale=null, $default=null, $null=null)
+    {
+        // protected
+        $this->_base      = $base;
+
+        // public
+        $this->_name      = $name;
+        $this->_type      = $type;
+        $this->_limit     = $limit;
+        $this->_precision = $precision;
+        $this->_scale     = $scale;
+        $this->_default   = $default;
+        $this->_null      = $null;
+    }
+
+    /*##########################################################################
+    # Public
+    ##########################################################################*/
+
+    /**
+     * @return  string
+     */
+    public function toSql()
+    {
+        $sql = $this->_base->quoteColumnName($this->_name).' ';
+        try {
+            $sql .= $this->_base->typeToSql($this->_type,      $this->_limit,
+                                            $this->_precision, $this->_scale);
+        } catch (Exception $e) {
+            $sql .= $this->_type;
+        }
+        return $this->_addColumnOptions($sql, array('null'    => $this->_null,
+                                                    'default' => $this->_default));
+    }
+
+    /**
+     * @return  string
+     */
+    public function __toString()
+    {
+        return $this->toSql();
+    }
+
+
+    /*##########################################################################
+    # Accessor
+    ##########################################################################*/
+
+    /**
+     * @return  string
+     */
+    public function getName()
+    {
+        return $this->_name;
+    }
+
+    /**
+     * @return  string
+     */
+    public function getDefault()
+    {
+        return $this->_default;
+    }
+
+    /**
+     * @return  string
+     */
+    public function getType()
+    {
+        return $this->_type;
+    }
+
+    /**
+     * @return  string
+     */
+    public function getSqlType()
+    {
+        try {
+            return $this->_base->typeToSql($this->_type, $this->_limit, $this->_precision, $this->_scale);
+        } catch (Exception $e) {
+            return $this->_type;
+        }
+    }
+
+    /**
+     * @return  int
+     */
+    public function getLimit()
+    {
+        return $this->_limit;
+    }
+
+    /**
+     * @return  int
+     */
+    public function precision()
+    {
+        return $this->_precision;
+    }
+
+    /**
+     * @return  int
+     */
+    public function scale()
+    {
+        return $this->_scale;
+    }
+
+    /**
+     * @return  boolean
+     */
+    public function isNull()
+    {
+        return $this->_null;
+    }
+
+    /**
+     * @param   string
+     */
+    public function setName($name)
+    {
+        $this->_name = $name;
+    }
+
+    /**
+     * @param  string
+     */
+    public function setDefault($default)
+    {
+        $this->_default = $default;
+    }
+
+    /**
+     * @param  string
+     */
+    public function setType($type)
+    {
+        $this->_type = $type;
+    }
+
+    /**
+     * @param  int
+     */
+    public function setLimit($limit)
+    {
+        $this->_limit = $limit;
+    }
+
+    /**
+     * @param  int
+     */
+    public function setPrecision($precision)
+    {
+        $this->_precision = $precision;
+    }
+
+    /**
+     * @param  int
+     */
+    public function setScale($scale)
+    {
+        $this->_scale = $scale;
+    }
+
+    /**
+     * @param  boolean
+     */
+    public function setNull($null)
+    {
+        $this->_null = $null;
+    }
+
+
+    /*##########################################################################
+    # Schema Statements
+    ##########################################################################*/
+
+    /**
+     * @param   string  $sql
+     * @param   array   $options
+     */
+    protected function _addColumnOptions($sql, $options)
+    {
+        return $this->_base->addColumnOptions($sql,
+            array_merge($options, array('column' => $this))
+        );
+    }
+
+}
diff --git a/framework/Db/lib/Horde/Db/Adapter/Base/Index.php b/framework/Db/lib/Horde/Db/Adapter/Base/Index.php
new file mode 100644 (file)
index 0000000..0509ece
--- /dev/null
@@ -0,0 +1,83 @@
+<?php
+/**
+ * Copyright 2007 Maintainable Software, LLC
+ * Copyright 2008-2009 The Horde Project (http://www.horde.org/)
+ *
+ * @author     Mike Naberezny <mike@maintainable.com>
+ * @author     Derek DeVries <derek@maintainable.com>
+ * @author     Chuck Hagenbuch <chuck@horde.org>
+ * @license    http://opensource.org/licenses/bsd-license.php
+ * @category   Horde
+ * @package    Horde_Db
+ * @subpackage Adapter
+ */
+
+/**
+ * @author     Mike Naberezny <mike@maintainable.com>
+ * @author     Derek DeVries <derek@maintainable.com>
+ * @author     Chuck Hagenbuch <chuck@horde.org>
+ * @license    http://opensource.org/licenses/bsd-license.php
+ * @category   Horde
+ * @package    Horde_Db
+ * @subpackage Adapter
+ */
+class Horde_Db_Adapter_Base_Index
+{
+    public $table;
+    public $name;
+    public $unique;
+    public $primary;
+    public $columns;
+
+
+    /*##########################################################################
+    # Construct/Destruct
+    ##########################################################################*/
+
+    /**
+     * Construct
+     *
+     * @param   string  $table    The table the index is on
+     * @param   string  $name     The index's name
+     * @param   boolean $primary  Is this a primary key?
+     * @param   boolean $unique   Is this a unique index?
+     * @param   array   $columns  The columns this index covers
+     */
+    public function __construct($table, $name, $primary, $unique, $columns)
+    {
+        $this->table   = $table;
+        $this->name    = $name;
+        $this->primary = $primary;
+        $this->unique  = $unique;
+        $this->columns = $columns;
+    }
+
+
+    /*##########################################################################
+    # Accessor
+    ##########################################################################*/
+
+    /**
+     * @return  string
+     */
+    public function getName()
+    {
+        return $this->name;
+    }
+
+
+    /*##########################################################################
+    # Casting
+    ##########################################################################*/
+
+    /**
+     * Comma-separated list of the columns in the primary key
+     *
+     * @return string
+     */
+    public function __toString()
+    {
+        return implode(',', $this->columns);
+    }
+
+}
diff --git a/framework/Db/lib/Horde/Db/Adapter/Base/Schema.php b/framework/Db/lib/Horde/Db/Adapter/Base/Schema.php
new file mode 100644 (file)
index 0000000..7c47fc9
--- /dev/null
@@ -0,0 +1,749 @@
+<?php
+/**
+ * Copyright 2007 Maintainable Software, LLC
+ * Copyright 2008-2009 The Horde Project (http://www.horde.org/)
+ *
+ * @author     Mike Naberezny <mike@maintainable.com>
+ * @author     Derek DeVries <derek@maintainable.com>
+ * @author     Chuck Hagenbuch <chuck@horde.org>
+ * @license    http://opensource.org/licenses/bsd-license.php
+ * @category   Horde
+ * @package    Horde_Db
+ * @subpackage Adapter
+ */
+
+/**
+ * @author     Mike Naberezny <mike@maintainable.com>
+ * @author     Derek DeVries <derek@maintainable.com>
+ * @author     Chuck Hagenbuch <chuck@horde.org>
+ * @license    http://opensource.org/licenses/bsd-license.php
+ * @category   Horde
+ * @package    Horde_Db
+ * @subpackage Adapter
+ */
+abstract class Horde_Db_Adapter_Base_Schema
+{
+    /**
+     * @var Cache object
+     */
+    protected $_cache = null;
+
+    /**
+     * @var Logger
+     */
+    protected $_logger = null;
+
+    /**
+     * @var Horde_Db_Adapter_Base
+     */
+    protected $_adapter = null;
+
+    /**
+     * @var array
+     */
+    protected $_adapterMethods = array();
+
+
+    /*##########################################################################
+    # Construct/Destruct
+    ##########################################################################*/
+
+    /**
+     * @param Horde_Db_Adapter_Base $adapter
+     * @param array $config
+     */
+    public function __construct($adapter, $config = array())
+    {
+        $this->_adapter = $adapter;
+        $this->_adapterMethods = array_flip(get_class_methods($adapter));
+
+        $this->_cache = isset($config['cache']) ? $config['cache'] : new Horde_Support_Stub;
+        $this->_logger = isset($config['logger']) ? $config['logger'] : new Horde_Support_Stub;
+    }
+
+
+    /*##########################################################################
+    # Object composition
+    ##########################################################################*/
+
+    /**
+     * Delegate calls to the adapter object.
+     *
+     * @param  string  $method
+     * @param  array   $args
+     */
+    public function __call($method, $args)
+    {
+        if (isset($this->_adapterMethods[$method])) {
+            return call_user_func_array(array($this->_adapter, $method), $args);
+        }
+
+        throw new BadMethodCallException('Call to undeclared method "'.$method.'"');
+    }
+
+
+    /*##########################################################################
+    # Quoting
+    ##########################################################################*/
+
+    /**
+     * Quotes the column value to help prevent
+     * {SQL injection attacks}[http://en.wikipedia.org/wiki/SQL_injection].
+     *
+     * @param   string  $value
+     * @param   string  $column
+     * @return  string
+     */
+    public function quote($value, $column=null)
+    {
+        if (is_object($value) && is_callable(array($value, 'quotedId'))) {
+            return $value->quotedId();
+        }
+
+        $type = isset($column) ? $column->getType() : null;
+
+        if (is_null($value)) {
+            return 'NULL';
+        } elseif ($value === true) {
+            return $type == 'integer' ? '1' : $this->quoteTrue();
+        } elseif ($value === false) {
+            return $type == 'integer' ? '0' : $this->quoteFalse();
+        } elseif (is_int($value) || is_float($value)) {
+            return $value;
+            /*@TODO
+          else
+            if value.acts_like?(:date) || value.acts_like?(:time)
+              "'#{quoted_date(value)}'"
+            else
+              "#{quoted_string_prefix}'#{quote_string(value.to_yaml)}'"
+            end
+            */
+        } elseif ($value instanceof DateTime || $value instanceof Horde_Date) {
+            return $this->_adapter->quoteString($type == 'integer'
+                                                ? $value->format('U')
+                                                : $value->format('Y-m-d H:i:s'));
+        } else {
+            /*@TODO
+          when String, ActiveSupport::Multibyte::Chars
+            value = value.to_s
+            if column && column.type == :binary && column.class.respond_to?(:string_to_binary)
+              "#{quoted_string_prefix}'#{quote_string(column.class.string_to_binary(value))}'" # ' (for ruby-mode)
+            elsif column && [:integer, :float].include?(column.type)
+              value = column.type == :integer ? value.to_i : value.to_f
+              value.to_s
+            else
+              "#{quoted_string_prefix}'#{quote_string(value)}'" # ' (for ruby-mode)
+            end
+            */
+            return $this->_adapter->quoteString($value);
+        }
+    }
+
+    /**
+     * Quotes a string, escaping any ' (single quote) and \ (backslash)
+     * characters..
+     *
+     * @param   string  $string
+     * @return  string
+     */
+    public function quoteString($string)
+    {
+        return "'".str_replace(array('\\', '\''), array('\\\\', '\\\''), $string)."'";
+    }
+
+    /**
+     * Returns a quoted form of the column name. This is highly adapter
+     * specific.
+     *
+     * @param   string  $name
+     * @return  string
+     */
+    abstract public function quoteColumnName($name);
+
+    /**
+     * Returns a quoted form of the table name. Defaults to column name quoting.
+     *
+     * @param   string  $name
+     * @return  string
+     */
+    public function quoteTableName($name)
+    {
+        return $this->quoteColumnName($name);
+    }
+
+    /**
+     * @return  string
+     */
+    public function quoteTrue()
+    {
+        return "'t'";
+    }
+
+    /**
+     * @return  string
+     */
+    public function quoteFalse()
+    {
+        return "'f'";
+    }
+
+    /**
+     * @return  string
+     */
+    public function quoteDate($value)
+    {
+        return $this->_adapter->quoteString((string)$value);
+    }
+
+    /**
+     * @return  string
+     */
+    public function quotedStringPrefix()
+    {
+        return '';
+    }
+
+
+    /*##########################################################################
+    # Schema Statements
+    ##########################################################################*/
+
+    /**
+     * Returns a Hash of mappings from the abstract data types to the native
+     * database types.  See TableDefinition#column for details on the recognized
+     * abstract data types.
+     *
+     * @return  array
+     */
+    public function nativeDatabaseTypes()
+    {
+        return array();
+    }
+
+    /**
+     * This is the maximum length a table alias can be
+     *
+     * @return  int
+     */
+    public function tableAliasLength()
+    {
+        return 255;
+    }
+
+    /**
+     * Truncates a table alias according to the limits of the current adapter.
+     *
+     * @param   string  $tableName
+     * @return  string
+     */
+    public function tableAliasFor($tableName)
+    {
+        $alias = substr($tableName, 0, $this->tableAliasLength());
+        return str_replace('.', '_', $alias);
+    }
+
+    /**
+     * @param   string  $name
+     * @return  array
+     */
+    abstract public function tables($name = null);
+
+    /**
+     * Get a Horde_Db_Adapter_Base_Table object for the table.
+     *
+     * @param  string  $tableName
+     * @param  string  $name
+     *
+     * @return Horde_Db_Adapter_Base_Table
+     */
+    public function table($tableName, $name = null)
+    {
+        return $this->componentFactory('Table', array(
+            $tableName,
+            $this->primaryKey($tableName),
+            $this->columns($tableName, $name),
+            $this->indexes($tableName, $name),
+        ));
+    }
+
+    /**
+     * Return a table's primary key
+     */
+    abstract public function primaryKey($tableName, $name = null);
+
+    /**
+     * Returns an array of indexes for the given table.
+     *
+     * @param   string  $tableName
+     * @param   string  $name
+     * @return  array
+     */
+    abstract public function indexes($tableName, $name = null);
+
+    /**
+     * Returns an array of Horde_Db_Adapter_Base_Column objects for the
+     * table specified by +table_name+.  See the concrete implementation for
+     * details on the expected parameter values.
+     *
+     * @param   string  $tableName
+     * @param   string  $name
+     * @return  array
+     */
+    abstract public function columns($tableName, $name = null);
+
+    /**
+     * Creates a new table
+     * There are two ways to work with #create_table.  You can use the block
+     * form or the regular form, like this:
+     *
+     * === Block form
+     *  # create_table() yields a TableDefinition instance
+     *  create_table(:suppliers) do |t|
+     *    t.column :name, :string, :limit => 60
+     *    # Other fields here
+     *  end
+     *
+     * === Regular form
+     *  create_table(:suppliers)
+     *  add_column(:suppliers, :name, :string, {:limit => 60})
+     *
+     * The +options+ hash can include the following keys:
+     * [<tt>:id</tt>]
+     *   Set to true or false to add/not add a primary key column
+     *   automatically.  Defaults to true.
+     * [<tt>:primary_key</tt>]
+     *   The name of the primary key, if one is to be added automatically.
+     *   Defaults to +id+.
+     * [<tt>:options</tt>]
+     *   Any extra options you want appended to the table definition.
+     * [<tt>:temporary</tt>]
+     *   Make a temporary table.
+     * [<tt>:force</tt>]
+     *   Set to true or false to drop the table before creating it.
+     *   Defaults to false.
+     *
+     * ===== Examples
+     * ====== Add a backend specific option to the generated SQL (MySQL)
+     *  create_table(:suppliers, :options => 'ENGINE=InnoDB DEFAULT CHARSET=utf8')
+     * generates:
+     *  CREATE TABLE suppliers (
+     *    id int(11) DEFAULT NULL auto_increment PRIMARY KEY
+     *  ) ENGINE=InnoDB DEFAULT CHARSET=utf8
+     *
+     * ====== Rename the primary key column
+     *  create_table(:objects, :primary_key => 'guid') do |t|
+     *    t.column :name, :string, :limit => 80
+     *  end
+     * generates:
+     *  CREATE TABLE objects (
+     *    guid int(11) DEFAULT NULL auto_increment PRIMARY KEY,
+     *    name varchar(80)
+     *  )
+     *
+     * ====== Do not add a primary key column
+     *  create_table(:categories_suppliers, :id => false) do |t|
+     *    t.column :category_id, :integer
+     *    t.column :supplier_id, :integer
+     *  end
+     * generates:
+     *  CREATE TABLE categories_suppliers_join (
+     *    category_id int,
+     *    supplier_id int
+     *  )
+     *
+     * See also TableDefinition#column for details on how to create columns.
+     *
+     * @param   string  $name
+     * @param   array   $options
+     */
+    public function createTable($name, $options=array())
+    {
+        $pk = isset($options['primaryKey']) && $options['primaryKey'] === false ? false : 'id';
+        $tableDefinition =
+            $this->componentFactory('TableDefinition', array($name, $this, $options));
+        if ($pk != false) {
+            $tableDefinition->primaryKey($pk);
+        }
+        return $tableDefinition;
+    }
+
+    /**
+     * Execute table creation
+     *
+     * @param   string  $name
+     * @param   array   $options
+     */
+    public function endTable($name, $options=array())
+    {
+        if ($name instanceof Horde_Db_Adapter_Base_TableDefinition) {
+            $tableDefinition = $name;
+            $options = array_merge($tableDefinition->getOptions(), $options);
+        } else {
+            $tableDefinition = $this->createTable($name, $options);
+        }
+
+        // drop previous
+        if (isset($options['force'])) {
+            $this->dropTable($tableDefinition->getName(), $options);
+        }
+
+        $temp = !empty($options['temporary']) ? 'TEMPORARY'           : null;
+        $opts = !empty($options['options'])   ? $options['options']   : null;
+
+        $sql  = "CREATE $temp TABLE ".$this->quoteTableName($tableDefinition->getName())." (\n".
+                  $tableDefinition->toSql()."\n".
+                ") $opts";
+        return $this->execute($sql);
+    }
+
+    /**
+     * Renames a table.
+     * ===== Example
+     *  rename_table('octopuses', 'octopi')
+     *
+     * @param   string  $name
+     * @param   string  $newName
+     */
+    abstract public function renameTable($name, $newName);
+
+    /**
+     * Drops a table from the database.
+     *
+     * @param   string  $name
+     */
+    public function dropTable($name)
+    {
+        $this->_clearTableCache($name);
+        return $this->execute('DROP TABLE ' . $this->quoteTableName($name));
+    }
+
+    /**
+     * Adds a new column to the named table.
+     * See TableDefinition#column for details of the options you can use.
+     *
+     * @param   string  $tableName
+     * @param   string  $columnName
+     * @param   string  $type
+     * @param   array   $options
+     */
+    public function addColumn($tableName, $columnName, $type, $options=array())
+    {
+        $this->_clearTableCache($tableName);
+
+        $limit     = isset($options['limit'])     ? $options['limit']     : null;
+        $precision = isset($options['precision']) ? $options['precision'] : null;
+        $scale     = isset($options['scale'])     ? $options['scale']     : null;
+
+        $sql = 'ALTER TABLE ' . $this->quoteTableName($tableName) .
+            ' ADD '.$this->quoteColumnName($columnName) .
+            ' '.$this->typeToSql($type, $limit, $precision, $scale);
+        $sql = $this->addColumnOptions($sql, $options);
+        return $this->execute($sql);
+    }
+
+    /**
+     * Removes the column from the table definition.
+     * ===== Examples
+     *  remove_column(:suppliers, :qualification)
+     *
+     * @param   string  $tableName
+     * @param   string  $columnName
+     */
+    public function removeColumn($tableName, $columnName)
+    {
+        $this->_clearTableCache($tableName);
+
+        $sql = 'ALTER TABLE ' . $this->quoteTableName($tableName).' DROP '.$this->quoteColumnName($columnName);
+        return $this->execute($sql);
+    }
+
+    /**
+     * Changes the column's definition according to the new options.
+     * See TableDefinition#column for details of the options you can use.
+     * ===== Examples
+     *  change_column(:suppliers, :name, :string, :limit => 80)
+     *  change_column(:accounts, :description, :text)
+     *
+     * @param   string  $tableName
+     * @param   string  $columnName
+     * @param   string  $type
+     * @param   array   $options
+     */
+    abstract public function changeColumn($tableName, $columnName, $type, $options=array());
+
+    /**
+     * Sets a new default value for a column.  If you want to set the default
+     * value to +NULL+, you are out of luck.  You need to
+     * DatabaseStatements#execute the apppropriate SQL statement yourself.
+     * ===== Examples
+     *  change_column_default(:suppliers, :qualification, 'new')
+     *  change_column_default(:accounts, :authorized, 1)
+     *
+     * @param   string  $tableName
+     * @param   string  $columnName
+     * @param   string  $default
+     */
+    abstract public function changeColumnDefault($tableName, $columnName, $default);
+
+    /**
+     * Renames a column.
+     * ===== Example
+     *  rename_column(:suppliers, :description, :name)
+     *
+     * @param   string  $tableName
+     * @param   string  $columnName
+     * @param   string  $newColumnName
+     */
+    abstract public function renameColumn($tableName, $columnName, $newColumnName);
+
+    /**
+     * Adds a new index to the table.  +column_name+ can be a single Symbol, or
+     * an Array of Symbols.
+     *
+     * The index will be named after the table and the first column names,
+     * unless you pass +:name+ as an option.
+     *
+     * When creating an index on multiple columns, the first column is used as a name
+     * for the index. For example, when you specify an index on two columns
+     * [+:first+, +:last+], the DBMS creates an index for both columns as well as an
+     * index for the first colum +:first+. Using just the first name for this index
+     * makes sense, because you will never have to create a singular index with this
+     * name.
+     *
+     * ===== Examples
+     * ====== Creating a simple index
+     *  add_index(:suppliers, :name)
+     * generates
+     *  CREATE INDEX suppliers_name_index ON suppliers(name)
+     *
+     * ====== Creating a unique index
+     *  add_index(:accounts, [:branch_id, :party_id], :unique => true)
+     * generates
+     *  CREATE UNIQUE INDEX accounts_branch_id_index ON accounts(branch_id, party_id)
+     *
+     * ====== Creating a named index
+     *  add_index(:accounts, [:branch_id, :party_id], :unique => true, :name => 'by_branch_party')
+     * generates
+     *  CREATE UNIQUE INDEX by_branch_party ON accounts(branch_id, party_id)
+     *
+     * @param   string  $tableName
+     * @param   string  $columnName
+     * @param   array   $options
+     */
+    public function addIndex($tableName, $columnName, $options=array())
+    {
+        $this->_clearTableCache($tableName);
+
+        $columnNames = (array)($columnName);
+        $indexName = $this->indexName($tableName, array('column' => $columnNames));
+
+        $indexType = !empty($options['unique']) ? "UNIQUE"         : null;
+        $indexName = !empty($options['name'])   ? $options['name'] : $indexName;
+
+        foreach ($columnNames as $colName) {
+            $quotedCols[] = $this->quoteColumnName($colName);
+        }
+        $quotedColumnNames = implode(', ', $quotedCols);
+        $sql = "CREATE $indexType INDEX ".$this->quoteColumnName($indexName).
+            'ON '.$this->quoteTableName($tableName) . " ($quotedColumnNames)";
+        return $this->execute($sql);
+    }
+
+    /**
+     * Remove the given index from the table.
+     *
+     * Remove the suppliers_name_index in the suppliers table (legacy support, use the second or third forms).
+     *   remove_index :suppliers, :name
+     * Remove the index named accounts_branch_id in the accounts table.
+     *   remove_index :accounts, :column => :branch_id
+     * Remove the index named by_branch_party in the accounts table.
+     *   remove_index :accounts, :name => :by_branch_party
+     *
+     * You can remove an index on multiple columns by specifying the first column.
+     *   add_index :accounts, [:username, :password]
+     *   remove_index :accounts, :username
+     *
+     * @param   string  $tableName
+     * @param   array   $options
+     */
+    public function removeIndex($tableName, $options=array())
+    {
+        $this->_clearTableCache($tableName);
+
+        $index = $this->indexName($tableName, $options);
+        $sql = "DROP INDEX ".$this->quoteColumnName($index).' ON ' . $this->quoteTableName($tableName);
+        return $this->execute($sql);
+    }
+
+    /**
+     * Get the name of the index
+     *
+     * @param   string  $tableName
+     * @param   array   $options
+     */
+    public function indexName($tableName, $options=array())
+    {
+        if (!is_array($options)) {
+            $options = array('column' => $options);
+        }
+
+        if (isset($options['column'])) {
+            $columns = (array)$options['column'];
+            return "index_{$tableName}_on_".implode('_and_', $columns);
+
+        } elseif (isset($options['name'])) {
+            return $options['name'];
+
+        } else {
+            throw new Horde_Db_Exception('You must specify the index name');
+        }
+    }
+
+    /**
+     * Returns a string of <tt>CREATE TABLE</tt> SQL statement(s) for recreating the
+     * entire structure of the database.
+     *
+     * @param   string  $table
+     * @return  string
+     */
+    abstract public function structureDump($table = null);
+
+    /**
+     * Recreate the given db
+     *
+     * @param   string  $name
+     */
+    public function recreateDatabase($name)
+    {
+        $this->dropDatabase($name);
+        return $this->createDatabase($name);
+    }
+
+    /**
+     * Create the given db
+     *
+     * @param   string  $name
+     */
+    abstract public function createDatabase($name);
+
+    /**
+     * Drop the given db
+     *
+     * @param   string  $name
+     */
+    abstract public function dropDatabase($name);
+
+    /**
+     * Get the name of the current db
+     *
+     * @return  string
+     */
+    abstract public function currentDatabase();
+
+    /**
+     * Should not be called normally, but this operation is non-destructive.
+     * The migrations module handles this automatically.
+     */
+    public function initializeSchemaInformation()
+    {
+        try {
+            $this->execute("CREATE TABLE schema_info (".
+                           "  version ".$this->typeToSql('integer').
+                           ")");
+            return $this->execute("INSERT INTO schema_info (version) VALUES (0)");
+        } catch (Exception $e) {}
+    }
+
+    /**
+     * The sql for this column type
+     *
+     * @param   string  $type
+     * @param   string  $limit
+     */
+    public function typeToSql($type, $limit=null, $precision=null, $scale=null)
+    {
+        $natives = $this->nativeDatabaseTypes();
+        $native = isset($natives[$type]) ? $natives[$type] : null;
+        if (empty($native)) { return $type; }
+
+        $sql = is_array($native) ? $native['name'] : $native;
+        if ($type == 'decimal') {
+            $nativePrec  = isset($native['precision']) ? $native['precision'] : null;
+            $nativeScale = isset($native['scale'])     ? $native['scale']     : null;
+
+            $precision = !empty($precision) ? $precision : $nativePrec;
+            $scale     = !empty($scale)     ? $scale     : $nativeScale;
+            if ($precision) {
+                $sql .= $scale ? "($precision, $scale)" : "($precision)";
+            }
+        } else {
+            $nativeLimit = is_array($native) ? $native['limit'] : null;
+            if ($limit = !empty($limit) ? $limit : $nativeLimit) {
+                $sql .= "($limit)";
+            }
+        }
+        return $sql;
+    }
+
+    /**
+     * Add default/null options to column sql
+     *
+     * @param   string  $sql
+     * @param   array   $options
+     */
+    public function addColumnOptions($sql, $options)
+    {
+        if (isset($options['null']) && $options['null'] === false) {
+            $sql .= ' NOT NULL';
+        }
+        if (isset($options['default'])) {
+            $default = $options['default'];
+            $column  = isset($options['column'])  ? $options['column']  : null;
+            $sql .= ' DEFAULT '.$this->quote($default, $column);
+        }
+        return $sql;
+    }
+
+    /**
+     * SELECT DISTINCT clause for a given set of columns and a given
+     * ORDER BY clause. Both PostgreSQL and Oracle override this for
+     * custom DISTINCT syntax.
+     *
+     * $connection->distinct("posts.id", "posts.created_at desc")
+     *
+     * @param   string  $columns
+     * @param   string  $orderBy
+     */
+    public function distinct($columns, $orderBy=null)
+    {
+        return "DISTINCT $columns";
+    }
+
+    /**
+     * ORDER BY clause for the passed order option.
+     * PostgreSQL overrides this due to its stricter standards compliance.
+     *
+     * @param   string  $sql
+     * @param   array   $options
+     * @return  string
+     */
+    public function addOrderByForAssocLimiting($sql, $options)
+    {
+        return $sql.'ORDER BY '.$options['order'];
+    }
+
+
+    /*##########################################################################
+    # Protected
+    ##########################################################################*/
+
+    /**
+     * We need to clear cache for tables when altering them at all
+     */
+    protected function _clearTableCache($tableName)
+    {
+        $this->_cache->set("tables/columns/$tableName", null);
+        $this->_cache->set("tables/indexes/$tableName", null);
+    }
+
+}
diff --git a/framework/Db/lib/Horde/Db/Adapter/Base/Table.php b/framework/Db/lib/Horde/Db/Adapter/Base/Table.php
new file mode 100644 (file)
index 0000000..f0dfa0c
--- /dev/null
@@ -0,0 +1,123 @@
+<?php
+/**
+ * Copyright 2007 Maintainable Software, LLC
+ * Copyright 2008 The Horde Project (http://www.horde.org/)
+ *
+ * @author     Mike Naberezny <mike@maintainable.com>
+ * @author     Derek DeVries <derek@maintainable.com>
+ * @author     Chuck Hagenbuch <chuck@horde.org>
+ * @license    http://opensource.org/licenses/bsd-license.php
+ * @category   Horde
+ * @package    Horde_Db
+ * @subpackage Adapter
+ */
+
+/**
+ * @author     Mike Naberezny <mike@maintainable.com>
+ * @author     Derek DeVries <derek@maintainable.com>
+ * @author     Chuck Hagenbuch <chuck@horde.org>
+ * @license    http://opensource.org/licenses/bsd-license.php
+ * @category   Horde
+ * @package    Horde_Db
+ * @subpackage Adapter
+ */
+class Horde_Db_Adapter_Base_Table
+{
+    protected $_name;
+    protected $_primaryKey;
+    protected $_columns;
+    protected $_indexes;
+
+
+    /*##########################################################################
+    # Construct/Destruct
+    ##########################################################################*/
+
+    /**
+     * Construct
+     *
+     * @param   string  $name     The table's name, such as <tt>supplier_id</tt> in <tt>supplier_id int(11)</tt>.
+     */
+    public function __construct($name, $primaryKey, $columns, $indexes)
+    {
+        $this->_name       = $name;
+        $this->_primaryKey = $primaryKey;
+        $this->_columns    = $columns;
+        $this->_indexes    = $indexes;
+    }
+
+
+    /*##########################################################################
+    # Accessor
+    ##########################################################################*/
+
+    /**
+     * @return  string
+     */
+    public function getName()
+    {
+        return $this->_name;
+    }
+
+    /**
+     * @return  mixed
+     */
+    public function getPrimaryKey()
+    {
+        return $this->_primaryKey;
+    }
+
+    /**
+     * @return  array
+     */
+    public function getColumns()
+    {
+        return $this->_columns;
+    }
+
+    /**
+     * @return  Horde_Db_Adapter_Base_Column
+     */
+    public function getColumn($column)
+    {
+        return isset($this->_columns[$column]) ? $this->_columns[$column] : null;
+    }
+
+    /**
+     * @return  array
+     */
+    public function getColumnNames()
+    {
+        $names = array();
+        foreach ($this->_columns as $column) {
+            $names[] = $column->getName();
+        }
+        return $names;
+    }
+
+    /**
+     * @return  array
+     */
+    public function getIndexes()
+    {
+        return $this->_indexes;
+    }
+
+    /**
+     * @return  array
+     */
+    public function getIndexNames()
+    {
+        $names = array();
+        foreach ($this->_indexes as $index) {
+            $names[] = $index->getName();
+        }
+        return $names;
+    }
+
+
+    /*##########################################################################
+    # Protected
+    ##########################################################################*/
+
+}
diff --git a/framework/Db/lib/Horde/Db/Adapter/Base/TableDefinition.php b/framework/Db/lib/Horde/Db/Adapter/Base/TableDefinition.php
new file mode 100644 (file)
index 0000000..a5af543
--- /dev/null
@@ -0,0 +1,235 @@
+<?php
+/**
+ * Copyright 2007 Maintainable Software, LLC
+ * Copyright 2008-2009 The Horde Project (http://www.horde.org/)
+ *
+ * @author     Mike Naberezny <mike@maintainable.com>
+ * @author     Derek DeVries <derek@maintainable.com>
+ * @author     Chuck Hagenbuch <chuck@horde.org>
+ * @license    http://opensource.org/licenses/bsd-license.php
+ * @category   Horde
+ * @package    Horde_Db
+ * @subpackage Adapter
+ */
+
+/**
+ * @author     Mike Naberezny <mike@maintainable.com>
+ * @author     Derek DeVries <derek@maintainable.com>
+ * @author     Chuck Hagenbuch <chuck@horde.org>
+ * @license    http://opensource.org/licenses/bsd-license.php
+ * @category   Horde
+ * @package    Horde_Db
+ * @subpackage Adapter
+ */
+class Horde_Db_Adapter_Base_TableDefinition implements ArrayAccess
+{
+    protected $_name    = null;
+    protected $_base    = null;
+    protected $_options = null;
+    protected $_columns = null;
+
+    /**
+     * Class Constructor
+     *
+     * @param  string  $name
+     * @param  Horde_Db_Adapter_Base_Schema  $base
+     * @param  array   $options
+     */
+    public function __construct($name, $base, $options=array())
+    {
+        $this->_name    = $name;
+        $this->_base    = $base;
+        $this->_options = $options;
+        $this->_columns = array();
+    }
+
+    /**
+     * @return  string
+     */
+    public function getName()
+    {
+        return $this->_name;
+    }
+
+    /**
+     * @return  array
+     */
+    public function getOptions()
+    {
+        return $this->_options;
+    }
+
+    /**
+     * @param   string  $name
+     */
+    public function primaryKey($name)
+    {
+        $natives = $this->_native();
+        $this->column($name, $natives['primaryKey']);
+    }
+
+    /**
+     * Instantiates a new column for the table.
+     * The +type+ parameter must be one of the following values:
+     * <tt>:primary_key</tt>, <tt>:string</tt>, <tt>:text</tt>,
+     * <tt>:integer</tt>, <tt>:float</tt>, <tt>:datetime</tt>,
+     * <tt>:timestamp</tt>, <tt>:time</tt>, <tt>:date</tt>,
+     * <tt>:binary</tt>, <tt>:boolean</tt>.
+     *
+     * Available options are (none of these exists by default):
+     * * <tt>:limit</tt>:
+     *   Requests a maximum column length (<tt>:string</tt>, <tt>:text</tt>,
+     *   <tt>:binary</tt> or <tt>:integer</tt> columns only)
+     * * <tt>:default</tt>:
+     *   The column's default value.  You cannot explicitely set the default
+     *   value to +NULL+.  Simply leave off this option if you want a +NULL+
+     *   default value.
+     * * <tt>:null</tt>:
+     *   Allows or disallows +NULL+ values in the column.  This option could
+     *   have been named <tt>:null_allowed</tt>.
+     *
+     * This method returns <tt>self</tt>.
+     *
+     * ===== Examples
+     *  # Assuming def is an instance of TableDefinition
+     *  def.column(:granted, :boolean)
+     *    #=> granted BOOLEAN
+     *
+     *  def.column(:picture, :binary, :limit => 2.megabytes)
+     *    #=> picture BLOB(2097152)
+     *
+     *  def.column(:sales_stage, :string, :limit => 20, :default => 'new', :null => false)
+     *    #=> sales_stage VARCHAR(20) DEFAULT 'new' NOT NULL
+     *
+     * @return  TableDefinition
+     */
+    public function column($name, $type, $options=array())
+    {
+        if ($this[$name]) {
+            $column = $this[$name];
+        } else {
+            $column = $this->_base->componentFactory('ColumnDefinition', array(
+                $this->_base, $name, $type));
+        }
+
+        $natives = $this->_native();
+        $opt = $options;
+
+        if (isset($opt['limit']) || isset($natives[$type])) {
+            $nativeLimit = isset($natives[$type]['limit']) ? $natives[$type]['limit'] : null;
+            $column->setLimit(isset($opt['limit']) ? $opt['limit'] : $nativeLimit);
+        }
+
+        $column->setPrecision(isset($opt['precision']) ? $opt['precision'] : null);
+        $column->setScale(isset($opt['scale'])         ? $opt['scale']     : null);
+        $column->setDefault(isset($opt['default'])     ? $opt['default']   : null);
+        $column->setNull(isset($opt['null'])           ? $opt['null']      : null);
+
+        $this[$name] ? $this[$name] = $column : $this->_columns[] = $column;
+        return $this;
+    }
+
+    /**
+     * Wrap up table creation block & create the table
+     */
+    public function end()
+    {
+        return $this->_base->endTable($this);
+    }
+
+    /**
+     * Returns a String whose contents are the column definitions
+     * concatenated together.  This string can then be pre and appended to
+     * to generate the final SQL to create the table.
+     *
+     * @return  string
+     */
+    public function toSql()
+    {
+        $cols = array();
+        foreach ($this->_columns as $col) { $cols[] = $col->toSql(); }
+
+        return "  ".implode(", \n  ", $cols);
+    }
+
+
+    /*##########################################################################
+    # ArrayAccess
+    ##########################################################################*/
+
+    /**
+     * ArrayAccess: Check if the given offset exists
+     *
+     * @param   int     $offset
+     * @return  boolean
+     */
+    public function offsetExists($offset)
+    {
+        foreach ($this->_columns as $column) {
+            if ($column->getName() == $offset) return true;
+        }
+        return false;
+    }
+
+    /**
+     * ArrayAccess: Return the value for the given offset.
+     *
+     * @param   int     $offset
+     * @return  object  {@link {@Horde_Db_Adapter_Base_ColumnDefinition}
+     */
+    public function offsetGet($offset)
+    {
+        if (!$this->offsetExists($offset)) {
+            return null;
+        }
+
+        foreach ($this->_columns as $column) {
+            if ($column->getName() == $offset) {
+                return $column;
+            }
+        }
+    }
+
+    /**
+     * ArrayAccess: Set value for given offset
+     *
+     * @param   int     $offset
+     * @param   mixed   $value
+     */
+    public function offsetSet($offset, $value)
+    {
+        foreach ($this->_columns as $key=>$column) {
+            if ($column->getName() == $offset) {
+                $this->_columns[$key] = $value;
+            }
+        }
+    }
+
+    /**
+     * ArrayAccess: remove element
+     *
+     * @param   int     $offset
+     */
+    public function offsetUnset($offset)
+    {
+        foreach ($this->_columns as $key=>$column) {
+            if ($column->getName() == $offset) {
+                unset($this->_columns[$key]);
+            }
+        }
+    }
+
+
+    /*##########################################################################
+    # Protected
+    ##########################################################################*/
+
+    /**
+     * Get the types
+     */
+    protected function _native()
+    {
+        return $this->_base->nativeDatabaseTypes();
+    }
+
+}
index 1156332..82db912 100644 (file)
@@ -21,7 +21,7 @@
  * @package    Horde_Db
  * @subpackage Adapter
  */
-class Horde_Db_Adapter_Mssql_Schema extends Horde_Db_Adapter_Abstract_Schema
+class Horde_Db_Adapter_Mssql_Schema extends Horde_Db_Adapter_Base_Schema
 {
     /*##########################################################################
     # Quoting
index c94f303..c118c53 100644 (file)
@@ -21,7 +21,7 @@
  * @package    Horde_Db
  * @subpackage Adapter
  */
-class Horde_Db_Adapter_Mysql_Column extends Horde_Db_Adapter_Abstract_Column
+class Horde_Db_Adapter_Mysql_Column extends Horde_Db_Adapter_Base_Column
 {
     /**
      * @var array
index 3580684..eb902fe 100644 (file)
@@ -21,7 +21,7 @@
  * @package    Horde_Db
  * @subpackage Adapter
  */
-class Horde_Db_Adapter_Mysql_Schema extends Horde_Db_Adapter_Abstract_Schema
+class Horde_Db_Adapter_Mysql_Schema extends Horde_Db_Adapter_Base_Schema
 {
     /*##########################################################################
     # Quoting
index 19a587e..35d4222 100644 (file)
@@ -23,7 +23,7 @@
  * @package    Horde_Db
  * @subpackage Adapter
  */
-class Horde_Db_Adapter_Mysqli extends Horde_Db_Adapter_Abstract
+class Horde_Db_Adapter_Mysqli extends Horde_Db_Adapter_Base
 {
     /**
      * Mysqli database connection object.
index 3ddb1fb..f4bb179 100644 (file)
@@ -21,7 +21,7 @@
  * @package    Horde_Db
  * @subpackage Adapter
  */
-class Horde_Db_Adapter_Oracle_Schema extends Horde_Db_Adapter_Abstract_Schema
+class Horde_Db_Adapter_Oracle_Schema extends Horde_Db_Adapter_Base_Schema
 {
     /*##########################################################################
     # Quoting
index b8cef05..895a37b 100644 (file)
@@ -21,7 +21,7 @@
  * @package    Horde_Db
  * @subpackage Adapter
  */
-class Horde_Db_Adapter_Postgresql_Column extends Horde_Db_Adapter_Abstract_Column
+class Horde_Db_Adapter_Postgresql_Column extends Horde_Db_Adapter_Base_Column
 {
     /*##########################################################################
     # Constants
index 9c73a98..74d1df9 100644 (file)
@@ -21,7 +21,7 @@
  * @package    Horde_Db
  * @subpackage Adapter
  */
-class Horde_Db_Adapter_Postgresql_Schema extends Horde_Db_Adapter_Abstract_Schema
+class Horde_Db_Adapter_Postgresql_Schema extends Horde_Db_Adapter_Base_Schema
 {
     /**
      * @var string
index ecaf810..7650749 100644 (file)
@@ -21,7 +21,7 @@
  * @package    Horde_Db
  * @subpackage Adapter
  */
-class Horde_Db_Adapter_Sqlite_Column extends Horde_Db_Adapter_Abstract_Column
+class Horde_Db_Adapter_Sqlite_Column extends Horde_Db_Adapter_Base_Column
 {
     /**
      * @var array
index 5442efe..c3ca43e 100644 (file)
@@ -21,7 +21,7 @@
  * @package    Horde_Db
  * @subpackage Adapter
  */
-class Horde_Db_Adapter_Sqlite_Schema extends Horde_Db_Adapter_Abstract_Schema
+class Horde_Db_Adapter_Sqlite_Schema extends Horde_Db_Adapter_Base_Schema
 {
     /*##########################################################################
     # Quoting
index ccff3fb..260c2f4 100644 (file)
@@ -38,14 +38,14 @@ http://pear.php.net/dtd/package-2.0.xsd">
     <dir name="Horde">
      <dir name="Db">
       <dir name="Adapter">
-       <dir name="Abstract">
+       <dir name="Base">
         <file name="Column.php" role="php" />
         <file name="ColumnDefinition.php" role="php" />
         <file name="Index.php" role="php" />
         <file name="Schema.php" role="php" />
         <file name="Table.php" role="php" />
         <file name="TableDefinition.php" role="php" />
-       </dir> <!-- /lib/Horde/Db/Adapter/Abstract -->
+       </dir> <!-- /lib/Horde/Db/Adapter/Base -->
        <dir name="Mssql">
         <file name="Schema.php" role="php" />
        </dir> <!-- /lib/Horde/Db/Adapter/Mssql -->
@@ -99,12 +99,12 @@ http://pear.php.net/dtd/package-2.0.xsd">
  </dependencies>
  <phprelease>
   <filelist>
-   <install name="lib/Horde/Db/Adapter/Abstract/Column.php" as="Horde/Db/Adapter/Abstract/Column.php" />
-   <install name="lib/Horde/Db/Adapter/Abstract/ColumnDefinition.php" as="Horde/Db/Adapter/Abstract/ColumnDefinition.php" />
-   <install name="lib/Horde/Db/Adapter/Abstract/Index.php" as="Horde/Db/Adapter/Abstract/Index.php" />
-   <install name="lib/Horde/Db/Adapter/Abstract/Schema.php" as="Horde/Db/Adapter/Abstract/Schema.php" />
-   <install name="lib/Horde/Db/Adapter/Abstract/Table.php" as="Horde/Db/Adapter/Abstract/Table.php" />
-   <install name="lib/Horde/Db/Adapter/Abstract/TableDefinition.php" as="Horde/Db/Adapter/Abstract/TableDefinition.php" />
+   <install name="lib/Horde/Db/Adapter/Base/Column.php" as="Horde/Db/Adapter/Base/Column.php" />
+   <install name="lib/Horde/Db/Adapter/Base/ColumnDefinition.php" as="Horde/Db/Adapter/Base/ColumnDefinition.php" />
+   <install name="lib/Horde/Db/Adapter/Base/Index.php" as="Horde/Db/Adapter/Base/Index.php" />
+   <install name="lib/Horde/Db/Adapter/Base/Schema.php" as="Horde/Db/Adapter/Base/Schema.php" />
+   <install name="lib/Horde/Db/Adapter/Base/Table.php" as="Horde/Db/Adapter/Base/Table.php" />
+   <install name="lib/Horde/Db/Adapter/Base/TableDefinition.php" as="Horde/Db/Adapter/Base/TableDefinition.php" />
    <install name="lib/Horde/Db/Adapter/Base.php" as="Horde/Db/Adapter/Base.php" />
 
    <install name="lib/Horde/Db/Adapter/Mssql/Schema.php" as="Horde/Db/Adapter/Mssql/Schema.php" />