<?xml version="1.0" encoding="UTF-8"?>
<!-- EN-Revision: 24249 -->
    <!-- Reviewed: no -->
<sect1 id="zend.db.profiler" xmlns:xi="http://www.w3.org/2001/XInclude">

    <title>Zend_Db_Profiler</title>

    <sect2 id="zend.db.profiler.introduction">

        <title>Introducción</title>

        <para>
            <classname>Zend_Db_Profiler</classname> puede ser habilitado para
            Perfilar las consultas. Los Perfiles incluyen la consulta procesada
            por el adaptador como el tiempo as transcurrido en la ejecución de
            las consultas, permitiendo inspeccionar las consultas realizadas win
            necesidad de agregar información de depuración extra en el código de
            las clases. El uso avanzado también permite que el desarrollador
            filtre las consultas que desea perfilar. </para>

        <para>Habilite el perfilador pasando una directiva al al constructor del
            adaptador, o pidiendole al adaptador permitirlo más adelante.</para>

        <programlisting language="php"><![CDATA[
$params = array(
    'host'     => '127.0.0.1',
    'username' => 'webuser',
    'password' => 'xxxxxxxx',
    'dbname'   => 'test'
    'profiler' => true  // enciende el perfilador
                        // establezca false para deshabilitar (está deshabilitado por defecto)
);

$db = Zend_Db::factory('PDO_MYSQL', $params);

// apagar el perfilador:
$db->getProfiler()->setEnabled(false);

// encender el perfilador:
$db->getProfiler()->setEnabled(true);
]]></programlisting>

        <para> El valor de la opción ' <property>profiler</property> ' es
            flexible. Es interpretada de distintas formas dependiendo del tipo.
            Normalmente, debería usar un valor booleano simple, pero otros tipos
            le permiten personalizar el comportamiento del perfilador. </para>

        <para> Un argumento booleano establece el perfilador como habilitado si
            el valor es <constant>TRUE</constant> , o deshabilitado si es
                <constant>FALSE</constant> . La clase del perfilador es el la
            clase de perfilador por defecto del adaptador,
                <classname>Zend_Db_Profiler</classname> . </para>

        <programlisting language="php"><![CDATA[
$params['profiler'] = true;
$db = Zend_Db::factory('PDO_MYSQL', $params);
]]></programlisting>

        <para> Una instancia del objeto perfilador hace que el adaptador use ese
            objeto. El tipo del objeto debe ser
                <classname>Zend_Db_Profiler</classname> o una subclase de este.
            Habilitar el perfilador se hace por separado. </para>

        <programlisting language="php"><![CDATA[
$profiler = MyProject_Db_Profiler();
$profiler->setEnabled(true);
$params['profiler'] = $profiler;
$db = Zend_Db::factory('PDO_MYSQL', $params);
]]></programlisting>

        <para> El argumento puede ser un array asociativo conteniendo algunas o
            todas las claves ' <property>enabled</property> ', '
                <property>instance</property> ', y ' <property>class</property>
            '. Las claves ' <property>enabled</property> ' e '
                <property>instance</property> ' corresponden a los tipos
            booleano y la instancia documentada previamente. La clave '
                <property>class</property> ' es usada para nombrar la clase que
            usará el perfilador personalizado. La clase debe ser
                <classname>Zend_Db_Profiler</classname> o una subclase. La clase
            es instanciada sin argumentos de constructor. La opción '
                <property>class</property> ' es ignorada cuando la opción '
                <property>instance</property> ' está dada. </para>

        <programlisting language="php"><![CDATA[
$params['profiler'] = array(
    'enabled' => true,
    'class'   => 'MyProject_Db_Profiler'
);
$db = Zend_Db::factory('PDO_MYSQL', $params);
]]></programlisting>

        <para> Finalmente, el argumento puede ser un objeto de tipo
                <classname>Zend_Config</classname> conteniendo las propiedades,
            que son tratadas como las claves de array descritas recién. Por
            ejemplo, un archivo " <filename>config.ini</filename> " puede
            contener los siguientes datos: </para>

        <programlisting language="ini"><![CDATA[
[main]
db.profiler.class   = "MyProject_Db_Profiler"
db.profiler.enabled = true
]]></programlisting>

        <para> Esta configuración puede ser aplicada con el siguiente código
                <acronym>PHP</acronym> : </para>
        <programlisting language="php"><![CDATA[
$config = new Zend_Config_Ini('config.ini', 'main');
$params['profiler'] = $config->db->profiler;
$db = Zend_Db::factory('PDO_MYSQL', $params);
]]></programlisting>
        <para> La propiedad ' <methodname>instance</methodname> ' debe ser usada
            como el siguiente ejemplo: </para>

        <programlisting language="php"><![CDATA[
$profiler = new MyProject_Db_Profiler();
$profiler->setEnabled(true);
$configData = array(
    'instance' => $profiler
    );
$config = new Zend_Config($configData);
$params['profiler'] = $config;
$db = Zend_Db::factory('PDO_MYSQL', $params);
]]></programlisting>

    </sect2>

    <sect2 id="zend.db.profiler.using">

        <title>Usando el Perfilador</title>

        <para> En este punto, obtenemos el perfilador usando el método
                <methodname>getProfiler()</methodname> del adaptador: </para>

        <programlisting language="php"><![CDATA[
$profiler = $db->getProfiler();
]]></programlisting>

        <para> Este retorna una instancia del objeto
                <classname>Zend_Db_Profiler</classname> . Con esta instancia, el
            desarrollador puede examinar las consultar usando una variedad de
            métodos: </para>

        <itemizedlist>
            <listitem>
                <para>
                    <methodname>getTotalNumQueries()</methodname> retorna el
                    número total de consultas que han sido perfiladas. </para>
            </listitem>
            <listitem>
                <para>
                    <methodname>getTotalElapsedSecs()</methodname> retorna el
                    número total de segundos transcurridos en todas las
                    consultas perfiladas. </para>
            </listitem>
            <listitem>
                <para>
                    <methodname>getQueryProfiles()</methodname> retorna un array
                    con todos los perfiles de consultas. </para>
            </listitem>
            <listitem>
                <para>
                    <methodname>getLastQueryProfile()</methodname> retorna el
                    último perfil (más reciente) de consulta, independientemente
                    de si la consulta ha terminado o no (si no lo ha hecho, la
                    hora de finalización será <constant>NULL</constant>). </para>
            </listitem>
            <listitem>
                <para>
                    <methodname>clear()</methodname> limpia los perfiles de
                    consulta de la pila. </para>
            </listitem>
        </itemizedlist>

        <para> El valor de retorno de
                <methodname>getLastQueryProfile()</methodname> y elementos
            individuales de <methodname>getQueryProfiles()</methodname> son
                <classname>Zend_Db_Profiler_Query</classname> objetos, que
            proporcionan la capacidad para inspeccionar cada una de las
            consultas: </para>

        <itemizedlist>
            <listitem>
                <para>
                    <methodname>getQuery()</methodname> retorna el texto SQL de
                    la consulta. El texto <acronym>SQL</acronym> de una
                    declaración preparada con parámetros es el texto al tiempo
                    en que la consulta fué preparada, por lo que contiene
                    marcadores de posición, no los valores utilizados cuando la
                    declaración se ejecuta. </para>
            </listitem>
            <listitem>
                <para>
                    <methodname>getQueryParams()</methodname> retorna un array
                    de los valores de los parámetros usados cuando se ejecuta
                    una consulta preparada. Este incluye ambos parámetros y
                    argumentos vinculados al método
                        <methodname>execute()</methodname> de la declaración.
                    Las claves del array son las posiciones (basado en 1) o
                    indices de parámetros nombrados (string). </para>
            </listitem>
            <listitem>
                <para>
                    <methodname>getElapsedSecs()</methodname> returna el número
                    de segundos que tuvo la consulta al correr. </para>
            </listitem>
        </itemizedlist>

        <para> La información que <classname>Zend_Db_Profiler</classname> provee
            es útil para perfilar cuellos de botella en aplicaciones, y para
            depurar consultas que han sido ejecutadas. Por instancia, para ver
            la consulta exacta que tuvo la última ejecución: </para>

        <programlisting language="php"><![CDATA[
$query = $profiler->getLastQueryProfile();

echo $query->getQuery();
]]></programlisting>

        <para>Tal vez una página se genera lentamente; use el perfilador para
            determinar primero el número total de segundos de todas las
            consultas, y luego recorrer paso a paso a través de las consultas
            para encontrar la más lenta:</para>

        <programlisting language="php"><![CDATA[
$totalTime    = $profiler->getTotalElapsedSecs();
$queryCount   = $profiler->getTotalNumQueries();
$longestTime  = 0;
$longestQuery = null;

foreach ($profiler->getQueryProfiles() as $query) {
    if ($query->getElapsedSecs() > $longestTime) {
        $longestTime  = $query->getElapsedSecs();
        $longestQuery = $query->getQuery();
    }
}

echo 'Ejecutadas ' . $queryCount . ' consultas en ' . $totalTime .
     ' segundos' . "\n";
echo 'Promedio de tiempo de consulta: ' . $totalTime / $queryCount .
     ' segundos' . "\n";
echo 'Consultas por segundo: ' . $queryCount / $totalTime . "\n";
echo 'Tardanza de la consulta más lenta: ' . $longestTime . "\n";
echo "Consulta más lenta: \n" . $longestQuery . "\n";
]]></programlisting>

    </sect2>

    <sect2 id="zend.db.profiler.advanced">

        <title>Uso avanzado del Perfilador</title>

        <para> Además de la inspección de consultas, el perfilador también le
            permite al desarrollador filtrar que consultas serán perfiladas. El
            siguiente método opera en una instancia de
                <classname>Zend_Db_Profiler</classname> : </para>

        <sect3 id="zend.db.profiler.advanced.filtertime">
            <title>Filtrar por tiempo transcurrido en consulta</title>

            <para>
                <methodname>setFilterElapsedSecs()</methodname> le permite al
                desarrolador establecer un tiempo mínimo antes de que una
                consulta se perfile. Para remover el filtro, pase un valor
                    <constant>NULL</constant> al método. </para>

            <programlisting language="php"><![CDATA[
// Solo perfilar consultas que tardan más de 5 segundos:
$profiler->setFilterElapsedSecs(5);

// Perfilar todas las consultas sin importar el tiempo:
$profiler->setFilterElapsedSecs(null);
]]></programlisting>
        </sect3>

        <sect3 id="zend.db.profiler.advanced.filtertype">
            <title>Filtrar por tipo de consulta</title>

            <para>
                <methodname>setFilterQueryType()</methodname> le permite al
                desarrollador establecer que tipo de consulta serán perfiladas;
                para perfilar multiples tipos, use un "OR" lógico. Los tipos de
                consulta se definen como las siguientes constantes de
                    <classname>Zend_Db_Profiler</classname> : </para>

            <itemizedlist>
                <listitem>
                    <para>
                        <constant>Zend_Db_Profiler::CONNECT</constant> :
                        operaciones de conexión o selección de base de datos.
                    </para>
                </listitem>
                <listitem>
                    <para>
                        <constant>Zend_Db_Profiler::QUERY</constant> : consultas
                        generales a la base de datos que no calzan con otros
                        tipos. </para>
                </listitem>
                <listitem>
                    <para>
                        <constant>Zend_Db_Profiler::INSERT</constant> :
                        cualquier consulta que agrega filas a la base de datos,
                        generalmente un <acronym>SQL</acronym> INSERT. </para>
                </listitem>
                <listitem>
                    <para>
                        <constant>Zend_Db_Profiler::UPDATE</constant> :
                        cualquier consulta que actualice registros existentes,
                        usualmente un <acronym>SQL</acronym> UPDATE. </para>
                </listitem>
                <listitem>
                    <para>
                        <constant>Zend_Db_Profiler::DELETE</constant> :
                        cualquier consulta que elimine datos existentes,
                        usualmente un <acronym>SQL</acronym> DELETE. </para>
                </listitem>
                <listitem>
                    <para>
                        <constant>Zend_Db_Profiler::SELECT</constant> :
                        cualquier consulta que retorne datos existentes,
                        usualmente un <acronym>SQL</acronym> SELECT. </para>
                </listitem>
                <listitem>
                    <para>
                        <constant>Zend_Db_Profiler::TRANSACTION</constant> :
                        cualquier operación transaccional, tal como iniciar una
                        transacción, confirmar, o revertir. </para>
                </listitem>
            </itemizedlist>

            <para> Asi como con <methodname>setFilterElapsedSecs()</methodname>
                , puedes remover cualquier filtro existente pasando un
                    <constant>NULL</constant> como único argumento. </para>

            <programlisting language="php"><![CDATA[
// Perfilar solo consultas SELECT
$profiler->setFilterQueryType(Zend_Db_Profiler::SELECT);

// Perfila consultas SELECT, INSERT, y UPDATE
$profiler->setFilterQueryType(Zend_Db_Profiler::SELECT |
                              Zend_Db_Profiler::INSERT |
                              Zend_Db_Profiler::UPDATE);

// Perfilar consultas DELETE
$profiler->setFilterQueryType(Zend_Db_Profiler::DELETE);

// Remover todos los filtros
$profiler->setFilterQueryType(null);
]]></programlisting>

        </sect3>

        <sect3 id="zend.db.profiler.advanced.getbytype">
            <title>Obtener perfiles por tipo de consulta</title>

            <para> Usando <methodname>setFilterQueryType()</methodname> puedes
                reducir los perfiles generados. Sin embargo, a veces puede ser
                más útil mantener todos los perfiles, pero ver sólo los que
                necesita en un determinado momento. Otra característica de
                    <methodname>getQueryProfiles()</methodname> es que puede
                este filtrado al-vuelo, pasando un tipo de consulta(o una
                combinación lógica de tipos de consulta) en el primer; vea <xref
                    linkend="zend.db.profiler.advanced.filtertype"/> para una
                lista las constantes de tipo de consulta. </para>

            <programlisting language="php"><![CDATA[
// Obtiene solo perfiles de consultas SELECT
$profiles = $profiler->getQueryProfiles(Zend_Db_Profiler::SELECT);

// Obtiene los perfiles de consultas SELECT, INSERT, y UPDATE
$profiles = $profiler->getQueryProfiles(Zend_Db_Profiler::SELECT |
                                        Zend_Db_Profiler::INSERT |
                                        Zend_Db_Profiler::UPDATE);

// Obtiene solo perfiles de consultas DELETE
$profiles = $profiler->getQueryProfiles(Zend_Db_Profiler::DELETE);
]]></programlisting>

        </sect3>

    </sect2>

    <sect2 id="zend.db.profiler.profilers">
        <title>Perfiladores Especializados</title>

        <para> Un Perfilador Especializado es un objeto que hereda de
                <classname>Zend_Db_Profiler</classname> . Los Perfiladores
            Especializados tratan la información de perfilado de maneras más
            especificas. </para>

        <xi:include href="Zend_Db_Profiler-Firebug.xml"/>

    </sect2>
</sect1>
