]> git.llucax.com Git - mecon/meconlib.git/commitdiff
Se agrega el MECON DBO.
authorLeandro Lucarella <llucax@gmail.com>
Mon, 6 Oct 2003 16:56:46 +0000 (16:56 +0000)
committerLeandro Lucarella <llucax@gmail.com>
Mon, 6 Oct 2003 16:56:46 +0000 (16:56 +0000)
doc/DBObject/DBObject.xmi [new file with mode: 0644]
doc/DBObject/xmi2code.config [new file with mode: 0644]
lib/MECON/DBO.php [new file with mode: 0644]
test/DBO.php [new file with mode: 0644]

diff --git a/doc/DBObject/DBObject.xmi b/doc/DBObject/DBObject.xmi
new file mode 100644 (file)
index 0000000..895508f
--- /dev/null
@@ -0,0 +1,160 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<XMI xmlns:UML="org.omg/standards/UML" verified="false" timestamp="" xmi.version="1.2" >
+ <XMI.header>
+  <XMI.documentation>
+   <XMI.exporter>umbrello uml modeller http://uml.sf.net</XMI.exporter>
+   <XMI.exporterVersion>1.1.5</XMI.exporterVersion>
+   <XMI.exporterEncoding>UnicodeUTF8</XMI.exporterEncoding>
+  </XMI.documentation>
+  <XMI.model xmi.name="DBObject" href="/home/luca/public_html/meconlib/doc/DBObject/DBObject.xmi" />
+  <XMI.metamodel xmi.name="UML" href="UML.xml" xmi.version="1.3" />
+ </XMI.header>
+ <XMI.content>
+  <docsettings viewid="12" documentation="" uniqueid="22" />
+  <umlobjects>
+   <UML:Class stereotype="interface" package="" xmi.id="16" abstract="1" documentation="Interfaz genérica para objetos que pueden ser guardados y/o operan con bases de datos.
+Utilizando esta interfaz se pueden hacer objetos genericos que manejen DBO, como por ejemplo tablas para listarlos. La forma común de recorrer una serie de resultados de una búsqueda de DBO puede verse en el método buscar()." name="MECON_DBO" static="0" scope="200" >
+    <UML:Operation stereotype="" package="" xmi.id="17" type="mixed" abstract="1" documentation="Carga el objeto desde una base de datos.
+Si hay un error, devuelve un PEAR_Error, si no devuelve la cantidad de objetos encontrados y carga el primero (si hay al menos un resultado).
+En el caso típico, se setea la propiedad que es la clave de la base de datos (siendo el resto nulas). Por ejemplo:
+@code
+class miDBO extends MECON_DBO {
+       // Definición...
+}
+$db = DB::connect('mi DSN');
+$miDBO = new MiDBO();
+$miDBO->id = 5;
+$e =$miDBO->cargar($db);
+if (PEAR::isError($e)) {
+       echo 'Hubo un error: ' . $e->getMessage();
+} elseif (!$e) {
+       echo 'No existe en la base de datos.';
+} elseif ($e == 1) {
+       var_dump($miDBO);
+} else {
+       echo &quot;Se encontraron $e elementos!';
+}
+@endcode
+@see buscar()
+@internal
+En el caso general, se hace un &lt;tt>SELECT&lt;/tt> con un &lt;tt>WHERE&lt;/tt> basado en los atributos no nulos concatenados con &lt;tt>AND&lt;/tt>." name="cargar" static="0" scope="200" >
+     <UML:Parameter stereotype="" package="" xmi.id="1" value="null" type="mixed" abstract="0" documentation="DB o DB_Result a usar para la carga." name="db" static="0" scope="200" />
+    </UML:Operation>
+    <UML:Operation stereotype="" package="" xmi.id="18" type="mixed" abstract="1" documentation="Guarda el objeto en una base de datos.
+Si alguna clave es &lt;tt>null&lt;/tt>, generalmente se guarda un objeto nuevo autoincrementando la clave en &lt;tt>null&lt;/tt>. Si todas las claves son distintas de &lt;tt>null&lt;/tt> y existe un objeto con las mismas claves, se modifica del existente los campos que el objeto no tenga en &lt;tt>null&lt;/tt>; si no existe da error a menos que se use el indicador &lt;tt>\$nuevo&lt;/tt>, en cuyo caso se agrega como nuevo. Si hay un error, devuelve un PEAR_Error. Si se guardan los datos bien, devuelve &lt;tt>true&lt;/tt>.
+Por ejemplo:
+@code
+class miDBO extends MECON_DBO {
+       // Definición...
+}
+$db = DB::connect('mi DSN');
+$miDBO = new MiDBO();
+$miDBO->id = 5;
+$miDBO->nombre = 'Petete';
+$miDBO->edad = 65;
+// Crea una nueva entrada en la DB.
+$e =$miDBO->guardar($db, true);
+if ($e === true) {
+       echo 'Se guardó bien.';
+} else {
+       echo 'Hubo un error: ' . $e->getMessage();
+}
+// Cambia la edad del objeto recién guardado.
+$miDBO->edad = 56;
+$e =$miDBO->guardar($db);
+if ($e === true) {
+       echo 'Se actualizó bien.';
+} else {
+       echo 'Hubo un error: '. $e->getMessage();
+}
+@endcode
+@internal
+En el caso general, se hace un &lt;tt>UPDATE&lt;/tt> con un &lt;tt>WHERE&lt;/tt> basado en la(s) clave(s) concatenadas con &lt;/tt>AND&lt;/tt>, y un &lt;tt>SET&lt;/tt> con los atributos no &lt;tt>nulos&lt;/tt>." name="guardar" static="0" scope="200" >
+     <UML:Parameter stereotype="" package="" xmi.id="1" value="null" type="DB" abstract="0" documentation="Base de datos a usar para guardar el objeto." name="db" static="0" scope="200" />
+     <UML:Parameter stereotype="" package="" xmi.id="2" value="false" type="bool" abstract="0" documentation="Indica si debe forzarse a guardar una entrada nueva en la DB. Se usa típicamente en bases cuya clave es externa y no puede especificarse un elemento nuevo con \c null en la clave." name="nuevo" static="0" scope="200" />
+    </UML:Operation>
+    <UML:Operation stereotype="" package="" xmi.id="19" type="mixed" abstract="1" documentation="Borra el objeto de una base de datos.
+Si hay un error, devuelve un PEAR_Error. Si no, devuelve la cantidad de objetos borrados de la base de datos.
+Por ejemplo:
+@code
+class miDBO extends MECON_DBO {
+       // Definición...
+}
+$db = DB::connect('mi DSN');
+$miDBO = new MiDBO();
+$miDBO->id = 5;
+$e =$miDBO->borrar($db);
+if (PEAR::isError($e)) {
+       echo 'Hubo un error: ' . $e->getMessage();
+} elseif (!$e) {
+       echo 'No estaba en la base de datos.';
+} elseif ($e == 1) {
+       echo 'Se borró de la base de datos';
+} else {
+       echo &quot;Se borraron $e elementos!';
+}
+@endcode
+@internal
+En el caso general, se hace un &lt;tt>DELETE&lt;/tt> con un &lt;tt>WHERE&lt;/tt> basado en los atributos no nulos concatenados con &lt;tt>AND&lt;/tt>." name="borrar" static="0" scope="200" >
+     <UML:Parameter stereotype="" package="" xmi.id="1" value="null" type="DB" abstract="0" documentation="Base de datos de donde borrar el objeto." name="db" static="0" scope="200" />
+    </UML:Operation>
+    <UML:Operation stereotype="" package="" xmi.id="20" type="mixed" abstract="1" documentation="Busca un objeto en una base de datos.
+Si hay un error, devuelve un PEAR_Error. Si no, devuelve un DB_Result con los resultados de la búsqueda.
+Por ejemplo:
+@code
+class miDBO extends MECON_DBO {
+       // Definición...
+}
+$db = DB::connect('mi DSN');
+$miDBO = new MiDBO();
+$miDBO->nombre = 'rez';
+$res = $miDBO->buscar($db, MECON_DBO_AND, 'nombre ASC');
+if (PEAR::isError($res)) {
+       echo 'Hubo un error.';
+} else {
+       echo 'Se encontraron ' . $res->numRows() . ' elementos.';
+       while (($miDBO->cargar($res) = $e) === true) {
+               var_dump($miDBO);
+       }
+       if (PEAR::isError($e)) {
+               echo 'Hubo un error: ' . $e->getMessage();
+       }
+}
+@endcode
+@see cargar()
+@internal
+Es similar a cargar, ya que se hace un &lt;tt>SELECT&lt;/tt> con un &lt;tt>WHERE&lt;/tt> basado en los atributos no nulos pero puede concatenarse con &lt;tt>AND&lt;/tt> u &lt;tt>OR&lt;/tt> y se busca con &lt;tt>LIKE&lt;/tt> para que dea más general." name="buscar" static="0" scope="200" >
+     <UML:Parameter stereotype="" package="" xmi.id="1" value="null" type="DB" abstract="0" documentation="Base de datos a utilizar en la búsqueda." name="db" static="0" scope="200" />
+     <UML:Parameter stereotype="" package="" xmi.id="2" value="MECON_DBO_OR" type="int" abstract="0" documentation="Indica que operador se usa para la búsqueda. Puede ser MECON_DBO_AND o MECON_DBO_OR." name="operador" static="0" scope="200" />
+     <UML:Parameter stereotype="" package="" xmi.id="3" value="''" type="mixed" abstract="0" documentation="Campos por los cuales ordenar. El formato es &lt;tt>campo (ASC|DESC)&lt;/tt> (siedo &lt;tt>ASC&lt;/tt> si se lo ordena de forma ascendente y &lt;tt>DESC&lt;/tt> si se lo ordena de forma descendente). Puede pasarse un &lt;em>string&lt;/em> o un &lt;em>array&lt;/em> con varios &lt;em>strings&lt;/em> con este formato para ordenarlo por más de un campo a la vez." name="orden" static="0" scope="200" />
+    </UML:Operation>
+   </UML:Class>
+  </umlobjects>
+  <diagrams>
+   <diagram snapgrid="0" showattsig="1" fillcolor="#ffffc0" zoom="100" showgrid="0" showopsig="1" usefillcolor="1" snapx="10" canvaswidth="733" snapy="10" showatts="1" xmi.id="12" documentation="" type="402" showops="1" showpackage="0" name="diagrama de clases" localid="30000" showstereotype="0" showscope="1" snapcsgrid="0" font="Helvetica,12,-1,5,50,0,0,0,0,0" linecolor="#ff0000" canvasheight="619" >
+    <widgets>
+     <UML:ClassWidget usesdiagramfillcolour="0" width="564" showattsigs="601" usesdiagramusefillcolour="0" x="59" linecolour="#ff0000" y="26" showopsigs="601" instancename="" usesdiagramlinecolour="0" fillcolour="#ffffc0" height="93" usefillcolor="1" showattributes="1" isinstance="0" xmi.id="16" showoperations="1" showpackage="0" showscope="1" showstereotype="0" font="Helvetica,10,-1,5,48,0,0,0,0,0" />
+    </widgets>
+    <messages/>
+    <associations/>
+   </diagram>
+  </diagrams>
+  <listview>
+   <listitem open="1" type="800" id="-1" label="Vistas" >
+    <listitem open="1" type="801" id="-1" label="Vista lógica" >
+     <listitem open="0" type="807" id="12" label="diagrama de clases" />
+     <listitem open="1" type="817" id="16" label="MECON_DBO" >
+      <listitem open="0" type="815" id="19" label="borrar" />
+      <listitem open="0" type="815" id="20" label="buscar" />
+      <listitem open="0" type="815" id="17" label="cargar" />
+      <listitem open="0" type="815" id="18" label="guardar" />
+     </listitem>
+    </listitem>
+    <listitem open="1" type="802" id="-1" label="Vista de caso de uso" />
+    <listitem open="1" type="821" id="-1" label="Component View" />
+    <listitem open="0" type="823" id="-1" label="Diagrams" />
+    <listitem open="1" type="827" id="-1" label="Deployment View" />
+   </listitem>
+  </listview>
+ </XMI.content>
+</XMI>
diff --git a/doc/DBObject/xmi2code.config b/doc/DBObject/xmi2code.config
new file mode 100644 (file)
index 0000000..5a3938e
--- /dev/null
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xmi2code>
+    <option key="target" value="*"/>
+    <option key="xmi-input" value="DBObject.xmi"/>
+    <option key="config-file" value="xmi2code.config"/>
+    <option key="config-file-set" value="false"/>
+    <option key="handler" value="umbrello"/>
+    <option key="generator-path" value="../../lib/"/>
+    <option key="use-package-as-dir" value="false"/>
+    <option key="use-underscores-as-dirs" value="true"/>
+    <option key="indent" value="    "/>
+    <option key="files-case" value="preserve"/>
+    <option key="generator" value="php.pear"/>
+    <option key="template-path" value=".."/>
+    <option key="php.template" value="xmi2code.tpl.php"/>
+    <option key="php.default-code" value="trigger_error('Not implemented!', E_USER_WARNING);"/>
+    <option key="php.pear.use-package-in-classnames" value="false"/>
+    <option key="php.pear.underscore-in-nonpublic" value="true"/>
+    <!-- user defined variables (for templates)  -->
+    <option key="author" value="Leandro Lucarella"/>
+    <option key="email" value="llucar@mecon.gov.ar"/>
+</xmi2code>
diff --git a/lib/MECON/DBO.php b/lib/MECON/DBO.php
new file mode 100644 (file)
index 0000000..978fb4c
--- /dev/null
@@ -0,0 +1,223 @@
+<?php /* vim: set binary expandtab tabstop=4 shiftwidth=4 textwidth=80:
+-------------------------------------------------------------------------------
+                             Ministerio de Economía
+                                    meconlib
+-------------------------------------------------------------------------------
+This file is part of meconlib.
+
+meconlib is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your option)
+any later version.
+
+meconlib is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+You should have received a copy of the GNU General Public License; if not,
+write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+Boston, MA  02111-1307  USA
+-------------------------------------------------------------------------------
+Creado: Thu Aug 28 16:33:47 2003
+Autor:  Leandro Lucarella <llucar@mecon.gov.ar>
+-------------------------------------------------------------------------------
+$Id$
+-----------------------------------------------------------------------------*/
+
+/**
+ * Indica que las condiciones deben concatenarse con <tt>OR</tt>.
+ */
+define('MECON_DBO_OR', 'OR');
+
+/**
+ * Indica que las condiciones deben concatenarse con <tt>AND</tt>.
+ */
+define('MECON_DBO_AND', 'AND');
+
+/**
+ * @example DBO.php
+ * Ejemplo de uso de DBO. Por ahora el ejemplo sólo implementa las funciones
+ * para consulta.
+ */
+
+// +X2C Class 16 :MECON_DBO
+/**
+ * Interfaz genérica para objetos que pueden ser guardados y/o operan con bases de datos.
+Utilizando esta interfaz se pueden hacer objetos genericos que manejen DBO, como por ejemplo tablas para listarlos. La forma común de recorrer una serie de resultados de una búsqueda de DBO puede verse en el método buscar().
+ *
+ * @access public
+ * @abstract
+ */
+class MECON_DBO {
+    // ~X2C
+
+    // +X2C Operation 17
+    /**
+     * Carga el objeto desde una base de datos.
+Si hay un error, devuelve un PEAR_Error, si no devuelve la cantidad de objetos encontrados y carga el primero (si hay al menos un resultado).
+En el caso típico, se setea la propiedad que es la clave de la base de datos (siendo el resto nulas). Por ejemplo:
+@code
+class miDBO extends MECON_DBO {
+       // Definición...
+}
+$db = DB::connect('mi DSN');
+$miDBO = new MiDBO();
+$miDBO->id = 5;
+$e =$miDBO->cargar($db);
+if (PEAR::isError($e)) {
+       echo 'Hubo un error: ' . $e->getMessage();
+} elseif (!$e) {
+       echo 'No existe en la base de datos.';
+} elseif ($e == 1) {
+       var_dump($miDBO);
+} else {
+       echo "Se encontraron $e elementos!';
+}
+@endcode
+@see buscar()
+@internal
+En el caso general, se hace un <tt>SELECT</tt> con un <tt>WHERE</tt> basado en los atributos no nulos concatenados con <tt>AND</tt>.
+     *
+     * @param  mixed $db DB o DB_Result a usar para la carga.
+     *
+     * @return mixed
+     * @access public
+     * @abstract
+     */
+    function cargar($db = null) // ~X2C
+    {
+        trigger_error('Not implemented!', E_USER_WARNING);
+    }
+    // -X2C
+
+    // +X2C Operation 18
+    /**
+     * Guarda el objeto en una base de datos.
+Si alguna clave es <tt>null</tt>, generalmente se guarda un objeto nuevo autoincrementando la clave en <tt>null</tt>. Si todas las claves son distintas de <tt>null</tt> y existe un objeto con las mismas claves, se modifica del existente los campos que el objeto no tenga en <tt>null</tt>; si no existe da error a menos que se use el indicador <tt>\$nuevo</tt>, en cuyo caso se agrega como nuevo. Si hay un error, devuelve un PEAR_Error. Si se guardan los datos bien, devuelve <tt>true</tt>.
+Por ejemplo:
+@code
+class miDBO extends MECON_DBO {
+       // Definición...
+}
+$db = DB::connect('mi DSN');
+$miDBO = new MiDBO();
+$miDBO->id = 5;
+$miDBO->nombre = 'Petete';
+$miDBO->edad = 65;
+// Crea una nueva entrada en la DB.
+$e =$miDBO->guardar($db, true);
+if ($e === true) {
+       echo 'Se guardó bien.';
+} else {
+       echo 'Hubo un error: ' . $e->getMessage();
+}
+// Cambia la edad del objeto recién guardado.
+$miDBO->edad = 56;
+$e =$miDBO->guardar($db);
+if ($e === true) {
+       echo 'Se actualizó bien.';
+} else {
+       echo 'Hubo un error: '. $e->getMessage();
+}
+@endcode
+@internal
+En el caso general, se hace un <tt>UPDATE</tt> con un <tt>WHERE</tt> basado en la(s) clave(s) concatenadas con </tt>AND</tt>, y un <tt>SET</tt> con los atributos no <tt>nulos</tt>.
+     *
+     * @param  DB $db Base de datos a usar para guardar el objeto.
+     * @param  bool $nuevo Indica si debe forzarse a guardar una entrada nueva en la DB. Se usa típicamente en bases cuya clave es externa y no puede especificarse un elemento nuevo con \c null en la clave.
+     *
+     * @return mixed
+     * @access public
+     * @abstract
+     */
+    function guardar($db = null, $nuevo = false) // ~X2C
+    {
+        trigger_error('Not implemented!', E_USER_WARNING);
+    }
+    // -X2C
+
+    // +X2C Operation 19
+    /**
+     * Borra el objeto de una base de datos.
+Si hay un error, devuelve un PEAR_Error. Si no, devuelve la cantidad de objetos borrados de la base de datos.
+Por ejemplo:
+@code
+class miDBO extends MECON_DBO {
+       // Definición...
+}
+$db = DB::connect('mi DSN');
+$miDBO = new MiDBO();
+$miDBO->id = 5;
+$e =$miDBO->borrar($db);
+if (PEAR::isError($e)) {
+       echo 'Hubo un error: ' . $e->getMessage();
+} elseif (!$e) {
+       echo 'No estaba en la base de datos.';
+} elseif ($e == 1) {
+       echo 'Se borró de la base de datos';
+} else {
+       echo "Se borraron $e elementos!';
+}
+@endcode
+@internal
+En el caso general, se hace un <tt>DELETE</tt> con un <tt>WHERE</tt> basado en los atributos no nulos concatenados con <tt>AND</tt>.
+     *
+     * @param  DB $db Base de datos de donde borrar el objeto.
+     *
+     * @return mixed
+     * @access public
+     * @abstract
+     */
+    function borrar($db = null) // ~X2C
+    {
+        trigger_error('Not implemented!', E_USER_WARNING);
+    }
+    // -X2C
+
+    // +X2C Operation 20
+    /**
+     * Busca un objeto en una base de datos.
+Si hay un error, devuelve un PEAR_Error. Si no, devuelve un DB_Result con los resultados de la búsqueda.
+Por ejemplo:
+@code
+class miDBO extends MECON_DBO {
+       // Definición...
+}
+$db = DB::connect('mi DSN');
+$miDBO = new MiDBO();
+$miDBO->nombre = 'rez';
+$res = $miDBO->buscar($db, MECON_DBO_AND, 'nombre ASC');
+if (PEAR::isError($res)) {
+       echo 'Hubo un error.';
+} else {
+       echo 'Se encontraron ' . $res->numRows() . ' elementos.';
+       while (($miDBO->cargar($res) = $e) === true) {
+               var_dump($miDBO);
+       }
+       if (PEAR::isError($e)) {
+               echo 'Hubo un error: ' . $e->getMessage();
+       }
+}
+@endcode
+@see cargar()
+@example DBO.php
+@internal
+Es similar a cargar, ya que se hace un <tt>SELECT</tt> con un <tt>WHERE</tt> basado en los atributos no nulos pero puede concatenarse con <tt>AND</tt> u <tt>OR</tt> y se busca con <tt>LIKE</tt> para que dea más general.
+     *
+     * @param  DB $db Base de datos a utilizar en la búsqueda.
+     * @param  int $operador Indica que operador se usa para la búsqueda. Puede ser MECON_DBO_AND o MECON_DBO_OR.
+     * @param  mixed $orden Campos por los cuales ordenar. El formato es <tt>campo (ASC|DESC)</tt> (siedo <tt>ASC</tt> si se lo ordena de forma ascendente y <tt>DESC</tt> si se lo ordena de forma descendente). Puede pasarse un <em>string</em> o un <em>array</em> con varios <em>strings</em> con este formato para ordenarlo por más de un campo a la vez.
+     *
+     * @return mixed
+     * @access public
+     * @abstract
+     */
+    function buscar($db = null, $operador = MECON_DBO_OR, $orden = '') // ~X2C
+    {
+        trigger_error('Not implemented!', E_USER_WARNING);
+    }
+    // -X2C
+
+} // -X2C Class :MECON_DBO
+
+?>
\ No newline at end of file
diff --git a/test/DBO.php b/test/DBO.php
new file mode 100644 (file)
index 0000000..410753c
--- /dev/null
@@ -0,0 +1,133 @@
+<?
+
+require_once 'DB.php';
+require_once 'Date.php';
+require_once '../lib/MECON/DBO.php';
+
+class Agente extends MECON_DBO {
+
+    // DSN por default.
+    var $dsn = 'mysql://intranet:intranet@bal747f.mecon.ar/novedades';
+    var $dni;
+    var $nombre;
+    var $dep;
+    // Date.
+    var $nac;
+
+    function Agente($dni) {
+        $this->dni = $dni;
+    }
+
+    function limpiar() {
+        $this->dni = null;
+        $this->nombre = null;
+        $this->dep = null;
+        $this->nac = null;
+    }
+
+    function cargar($db = null) {
+        // Si no me pasan la DB, creo una.
+        if (is_null($db)) {
+            $db = DB::connect($this->dsn);
+            // Si hay error lo devuelve.
+            if (DB::isError($db)) {
+                return $db;
+            }
+        }
+        // Si es un resultado, obtengo los elemento.
+        if (is_a($db, 'db_result')) {
+            $res = $db->fetchRow(DB_FETCHMODE_ASSOC);
+            // Si hay error lo devuelve.
+            if (DB::isError($res)) {
+                return $res;
+            }
+        // Si no es un resultado, obtengo el elemento.
+        } else {
+            $res = $db->getRow(
+                'SELECT nrodoc, nombre, dependencia, fecha_nac
+                    FROM novedades.web003
+                    WHERE nrodoc = ' . $db->quote($this->dni),
+                null,
+                DB_FETCHMODE_ASSOC
+            );
+            // Si hay error lo devuelve.
+            if (DB::isError($res)) {
+                return $res;
+            }
+        }
+        // Si no hay resultados devuelve false.
+        if (!$res) {
+            return false;
+        }
+        // Si tenemos resultados, cargamos los datos.
+        $this->dni = $res['nrodoc'];
+        $this->nombre = ucwords(strtolower($res['nombre']));
+        $this->dep = ucwords(strtolower($res['dependencia']));
+        preg_match('/(\d{2})(\d{2})(\d{4})/', $res['fecha_nac'], $m);
+        $this->nac = new Date("$m[3]-$m[2]-$m[1] 00:00:00");
+        return true;
+    }
+
+    function buscar($db = null, $operador = MECON_DBO_OR, $orden = 'nombre ASC') {
+        // Si no me pasan la DB, creo una.
+        if (is_null($db)) {
+            $db = DB::connect($this->dsn);
+            // Si hay error lo devuelve.
+            if (DB::isError($db)) {
+                return $db;
+            }
+        }
+        // Armo el WHERE.
+        $where = array();
+        // Si tiene nombre, agrego a la búsqueda.
+        if (!is_null($this->nombre)) {
+            $where[] = 'W.nombre LIKE ' . $db->quote("%$this->nombre%");
+        }
+        // Si tiene dep, agrego a la búsqueda.
+        if (!is_null($this->dep)) {
+            $where[] = 'W.dependencia LIKE ' . $db->quote("%$this->dep%");
+        }
+        // Si tiene nac, agrego a la búsqueda.
+        if (!is_null($this->nac)) {
+            $where[] = 'W.fecha_nac LIKE '
+                . $db->quote('%' . $this->nac->format('%d%m%Y') . '%');
+        }
+        if ($where) {
+            $where = 'WHERE ' . join (" $operador ", $where);
+        } else {
+            $where = '';
+        }
+        // Armo el ORDER BY.
+        if (is_string($orden)) {
+            $orden = array($orden);
+        }
+        if ($orden) {
+            $orden = 'ORDER BY ' . join(', ', $orden);
+        }
+        return $db->query(
+            "SELECT nrodoc, nombre, dependencia, fecha_nac
+                FROM novedades.web003 as W $where $orden");
+    }
+
+}
+
+$agente = new Agente(27215947);
+echo 'Carga: '; var_dump($e = $agente->cargar()); echo "\n";
+if (PEAR::isError($e)) {
+    die('Error: ' . $e->getMessage() . "\n");
+}
+echo ' '; var_dump($agente); echo "\n";
+$agente->limpiar();
+$agente->nombre = 'sklar';
+echo 'Búsqueda: '; var_dump(is_a($res = $agente->buscar(), 'db_result')); echo "\n";
+if (PEAR::isError($res)) {
+    die('Error: ' . $res->getMessage() . "\n");
+}
+while ($e = $agente->cargar($res)) {
+    if (PEAR::isError($e)) {
+        die('Error: ' . $e->getMessage() . "\n");
+    }
+    echo '  Agente: '; var_dump($agente); echo "\n";
+}
+
+?>