Joomla! Platform 3: Bases de datos

Ya llegó el calor, terminaron los exámenes de junio y parece que ya llega el verano, aunque hace poco aún estaba lloviendo en la costa mediterránea de España. Yo sigo con lo mío y hoy les traigo un acceso a bases de datos usando SQLite, una base de datos de dominio público, embebida, no necesita instalación y simplemente con que PHP tenga activada la extensión para ello ya podemos usarla.
Como viene siendo costumbre de la serie que escribo, me voy a centrar en el uso en un servidor web, con lo que el ejemplo es una página web. Se puede también ejecutar en línea de comando pero yo no uso PHP de esa forma así que… vamos al grano.


Materiales

  1. El framework Joomla Platform. Yo he usado la versión 12.3, la oficial veo que es la 12.1 y está en desarrollo la 13.1. Aquí hay más información para los curiosos como yo.
  2. Un entorno de desarrollo. Aquí ya para gustos estan los colores, Eclipse va muy bien y es multiplataforma.
  3. Un servidor para ejecutarlo. XAMPP funciona muy bien y también es multiplataforma.

Empezando

Descomprimo el framework en el directorio si es que no lo tengo ya, entonces hay que crear un fichero .php como en el ejemplo siguiente y veremos rápidamente como funciona:

...
<?php

// se importa la Plataforma Joomla.
require_once 'libraries/import.php';

class laWeb extends JApplicationWeb {
protected function doExecute()
{
$this->setBody("<html><body>");
$this->appendBody("<h1>Plataforma Joomla! SQLite</h1>");

// vector de configuración de la base de datos
// para sqlite sólo hace falta ésto
$option = array();
$option['driver'] = 'sqlite'; // tipo de bd
//$option['host'] = 'direccionhost.com'; // host
//$option['user'] = 'usuario'; //
//$option['password'] = 'contraseña'; //
$option['database'] = 'bdpruebas.sqlite'; // nombre de la bd
//$option['prefix'] = 'pref_'; // prefijo
$dbo = JDatabaseDriver::getInstance($option);

// se puede abreviar usando:
//$dbo = JDatabaseDriver::getInstance(array('driver' => 'sqlite', 'database' => 'bdpruebas.sqlite'));


// crea una tabla para las pruebas, la borra si existe
$dbo->setQuery("DROP TABLE IF EXISTS aleatorios");
$dbo->execute();
$dbo->setQuery('CREATE TABLE IF NOT EXISTS aleatorios (id INTEGER PRIMARY KEY, numero INTEGER)');
$dbo->execute();
$this->appendBody("<p>Creada la base de datos...</p>");

// inserta unos datos en la BD
for ($i = 0; $i < 10; $i++) {
$dbo->setQuery('INSERT INTO aleatorios (id, numero) VALUES (' . $i . ', ' . rand(0,99) . ');');
$dbo->execute();
}
$this->appendBody("<p>Insertados datos...</p>");

// lee la tabla
$this->appendBody("Listando con loadRowList ");
$dbo->setQuery("SELECT * FROM aleatorios;");
$resultados = $dbo->loadRowList();
foreach ($resultados as $res){
$this->appendBody( "<p>" . $res[0] . ", " . $res[1] . "</p>");
}

// lee la tabla de otra forma
$this->appendBody("Listando con loadAssocList ");
$dbo->setQuery("SELECT * FROM aleatorios;");
$resultados = $dbo->loadAssocList();
foreach ($resultados as $res){
$this->appendBody( "<p>" . $res['id'] . ", " . $res['numero'] . "</p>");
}

// lee de nuevo la tabla de otra forma
$this->appendBody("Listando con loadObjectList ");
$dbo->setQuery("SELECT * FROM aleatorios;");
$resultados = $dbo->loadObjectList();
foreach ($resultados as $res){
$this->appendBody( "<p>" . $res->id . ", " . $res->numero . "</p>");
}

$this->appendBody("</body></html>");

}
}

JApplicationWeb::getInstance("laWeb")->execute();
...

El ejemplo en descarga está aquí.

El resultado de ejecutarlo desde el navegador debe ser algo tal que así:

Plataforma Joomla! SQLite

Creada la base de datos…
Insertados datos…
Listando con loadRowList
0, 55
1, 4
2, 1
3, 76
4, 95
5, 62
6, 63
7, 16
8, 52
9, 73
Listando con loadAssocList
0, 55
1, 4
2, 1
3, 76
4, 95
5, 62
6, 63
7, 16
8, 52
9, 73
Listando con loadObjectList
0, 55
1, 4
2, 1
3, 76
4, 95
5, 62
6, 63
7, 16
8, 52
9, 73

Explicaciones

Lo que hace el programa es crear el archivo bdpruebas.sqlite si no existe, es un comportamiento peculiar de SQLite. Si usásemos otra base de datos como PostgreSQL o MySQL podríamos usar las sentencias SQL propias de cada base de datos. El código usa las funciones para cargar tablas de datos loadRowList, loadAssocList y loadObjectList. Ésto nos devuelve un objeto que almacenará los datos de la base de datos en nuestro programa. Hay otras funciones para cuando la consulta devuelve sólo una fila o sólo un dato por ejemplo.
Hasta aquí todo bien, pero entonces ¿porqué usar el framework y no usar directamente PHP como siempre sin framework?
Ahora a partir de las últimas versiones se han añadido más bases de datos aparte de la original MySQL, tenemos PostgreSQL, SQLServer, y se preveen el acceso a muchas otras. Ahora bien, tenemos una capa extra que nos va a independizar totalmente de la base de datos, siempre que no usemos las tradicionales sentencias SQL, como en el ejemplo anterior, y construyamos nuestra aplicación usando ésta herramienta. Puede que en un futuro querramos cambiar de base de datos o hacer posible que dicho cambio sea dinámico según configuración del usuario.

Independizando de la base de datos

La historia está en crear la query usando el framework. Tenemos la clase JDatabaseDriver que es la que nos provee de la conexión a la base de datos. Ahora sí, contruimos la $query usando la clase JDatabaseQuery y entonces obtendremos esa compatibilidad de las consultas, inserciones, actualizaciones y borrados de nuestro programa con varios tipos de bases de datos. He simplificado el ejemplo anterior:

...
<?php

// se importa la Plataforma Joomla.
require_once 'libraries/import.php';

class laWeb extends JApplicationWeb {
protected function doExecute()
{
$this->setBody("<html><body>");
$this->appendBody("<h1>Plataforma Joomla! Independizando de la base de datos</h1>");

//
$dbo = JDatabaseDriver::getInstance(array('driver' => 'sqlite', 'database' => 'bdpruebas.sqlite'));

// borrando los datos de la tabla aleatorios
// para tenerla limpia
$query = $dbo->getQuery(true);
$query->delete('aleatorios');
$dbo->setQuery($query);
$dbo->execute();

$this->appendBody("<p>Borrados los datos...</p>");

// inserta unos datos en la BD
for ($i = 0; $i < 10; $i++) {
// crear una nueva consulta
$query = $dbo->getQuery(true);

// se construye
$query->insert('aleatorios')
->columns('id, numero')
->values($i . ', ' . rand(0,99));

// se establece
$dbo->setQuery($query);

// se ejecuta
$dbo->execute();
}
$this->appendBody("<p>Insertados datos...</p>");

// consultado datos
$query->select('*')->from('aleatorios');
$dbo->setQuery($query);
$resultados = $dbo->loadObjectList();
foreach ($resultados as $res){
$this->appendBody( '<p>' . $res->id . ', ' . $res->numero . '</p>');
}

$this->appendBody("</body></html>");

}
}

JApplicationWeb::getInstance("laWeb")->execute();
...

Éste segundo ejemplo está en descarga aquí.

Utilizando la base de datos creada con el primer ejemplo, si guardamos éste segundo en otro fichero .php y lo ejecutamos en el navegador funcionará de forma similar. Ahora, si tenemos la base de datos distinta de SQLite, simplemente con cambiar la línea:

$dbo = JDatabaseDriver::getInstance(array('driver' => 'sqlite', 'database' => 'bdpruebas.sqlite'));

Haciendo la conexión con la base de datos que tengamos, nos aseguramos que el resto de consultas, inserciones, actualizaciones o borrados van a funcionar.

Terminando

Otra vez más, me remito para más información a la documentación oficial:

http://docs.joomla.org/J3.1:Accessing_the_database_using_JDatabase
http://api.joomla.org/Joomla-Platform/Database/JDatabaseQuery.html#insert

Éste post al final se ha hecho bien largo, ¡otro testamento! xDD Es que las bases de datos lo merecen ¿no cree?

Espero que sirva.
Saludos.

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *