\documentclass{article}
\usepackage{ulem}
\pagestyle{headings}
\begin{document}
\part{ Horde\_Db Library and Horde Database Migrations}
\section{ Horde DB: Usage by Example}
\subsection{ Get a Connection object}
\subsection{ Selecting Values}
\subsection{ Insert}
\subsection{ Delete}
\subsection{ Getting a DB handle from inside a Horde\_Core\_Application context}
\section{ Migrations: Usage by Example}
Migrations are PHP Class files in the /migration/ sub folder of an app or library. They can be run via the horde-db-migrate script or the web UI.\newline
They allow schema and data conversions forward and back.

Schema files prepend the lowercased class name with a version:

The first version's file would be 1\_\$app\_foo (usually 1\_\$app\_base\_tables) which would contain the class named \$AppFoo\footnote{http://example.com/index.php?page=AppFoo} (\$AppBaseTables\footnote{http://example.com/index.php?page=AppBaseTables}) derived from Horde\_Db\_Migration\_Base. See https://github.com/horde/skeleton/blob/master/migration/1\_skeleton\_base\_tables.php\footnote{https://github.com/horde/skeleton/blob/master/migration/1\_skeleton\_base\_tables.php} for a complete example.

These classes usually contain an up() and down() method to implement upgrades or downgrades to the next/previous schema.

Errors during Schema upgrades need to be handled by the implementer himself. There is no implicit rollback of schema upgrades which fail halfway through the up() method unless you implement an appropriate try/catch block yourself.

\subsection{ Adding a new table}
\subsection{Removing a table}
\subsection{ Adding a new column to an existing table}
\subsection{Dropping a column from an existing table}
\subsection{ Adding an index}
It's possible to use a helper function to check if an index is already set:

\begin{verbatim}

/**
 * Helper function to test if an index already exists
 */
private function hasIndex($tableName, $column)
{
    $indexedColumns = array();
    foreach ($this->indexes($tableName) as $index) {
        $indexedColumns = array_merge($indexedColumns, $index->columns);
    }

    if (is_array($column)) {
        foreach ($column as $entry) {
            return in_array($entry, $indexedColumns);
        }
    } else {
        return in_array($column, $indexedColumns);
    }
}
\end{verbatim}

Add the index

\begin{verbatim}

if (!$this->hasIndex('my_table', array('my_column', 'my_column2'))) {
    $this->addIndex('my_table', array('my_column', 'my_column2'));
}
\end{verbatim}

\subsection{ Adding a unique key / unique index}
It's also possible to add unique keys or a self defined names via the options:

\begin{verbatim}

if (!$this->hasIndex('my_table', 'my_column')) {
    $this->addIndex('my_table', 'my_column', array('unique' => true));
}
\end{verbatim}

\subsection{ Converting for Non-Horde or Pre-H4 schemas}
Check for all table's existence before adding them

\subsection{ Manipulating data while changing fields}
\end{document}
