Página 1 de 1

DBAL  Tema Solucionado

Publicado: 19 Oct 2014, 15:33
por towen

En phpBB se utiliza la Capa de Abstracción de la Base de Datos (DBAL, del inglés Database Abstraction Layer) para todas las operaciones referentes a bases de datos para lo que permite el uso de distintos gestores sin afectar la compatibilidad de las modificaciones. Todos los archivos de la DBAL se encuentran en includes/db/ junto con el archivo db_tools.php que permite hacer modificaciones en la estructura de las bases de datos y tablas. Se inicializa y conecta automáticamente en el archivo common.php por lo que el objeto $db y todos sus métodos están disponibles a nivel global. A continuación una lista de los métodos más importantes y como usarlos. Aclarar que esta guía se realizó en su día para phpBB 3.0.x


Métodos:

  1. sql_connect y sql_close

  2. sql_query

  3. sql_query_limit

  4. sql_fetchrow

  5. sql_fetchrowset

  6. sql_fetchfield

  7. sql_nextid

  8. sql_escape

  9. sql_build_array

  10. sql_in_set

  11. sql_multi_insert

  12. sql_build_query

  13. sql_affectedrows

  14. sql_freeresult

  15. sql_error


sql_connect y sql_close

Estos dos métodos no es necesario utilizarlos ya que phpBB crea automáticamente la conexión al comenzar la ejecución de un script y la cierra al terminar.

⬆️ Subir ⬆️

sql_query

Código: Seleccionar todo

$db->sql_query($query = '', $cache_ttl = 0)

Ejecuta una consulta SQL.

Argumentos

Spoiler
Mostrar

$query (cadena)

La consulta SQL a ejecutar.

$cache_ttl (entero)

Opcional, por defecto 0 para impedir que la consulta se guarde en caché. Indica el tiempo en segundos que la consulta se guardará en caché

Devuelve

Spoiler
Mostrar

Para consultas que devuelvan valores (SELECT principalmente que es la más usada) devuelve un recurso que puede usarse con métodos como sql_fetchrow o sql_fetchfield en caso de éxito o false en caso de error.
Para consultas de edición o adición de datos (UPDATE o INSERT principalmente) devuelve true en caso de éxito o false en caso de error.

Ejemplo

Código: Seleccionar todo

// las consultas de selección devuelven un recurso para utilizar con otros métodos como sql_fetchrow
$sql = 'SELECT forum_id, forum_name, parent_id, forum_type, left_id, right_id
    FROM ' . FORUMS_TABLE . '
    ORDER BY left_id ASC';
$result = $db->sql_query($sql, 600);

// las consultas de edición no devuelven ningún recurso que se pueda utilizar para mostrar información
$sql = 'UPDATE ' . FORUMS_TABLE . "
    SET forum_parents = '" . $db->sql_escape($forum_data['forum_parents']) . "'
    WHERE parent_id = " . $forum_data['parent_id'];
$db->sql_query($sql);

⬆️ Subir ⬆️

sql_query_limit

Código: Seleccionar todo

$db->sql_query_limit($query, $total, $offset = 0, $cache_ttl = 0)

Ejecuta una consulta SQL con límites. Debe utilizarse este método en lugar de agregar LIMIT a una consulta y ejecutarla con sql_query.

Argumentos

Spoiler
Mostrar

$query (cadena)

La consulta SQL a ejecutar.

$total (entero)

La cantidad de elementos que se seleccionarán.

$offset (entero)

Opcional. El número de la fila desde la cual se comenzará a seleccionar, por defecto 0 para comenzar desde el primer elemento (las filas se numeran comenzando desde 0).

$cache_ttl (entero)

Opcional, por defecto 0 para impedir que la consulta se guarde en caché. Indica el tiempo en segundos que la consulta se guardará en caché

Devuelve

Spoiler
Mostrar

Devuelve un recurso que puede usarse con métodos como sql_fetchrow o sql_fetchfield en caso de éxito o false en caso de error.

⬆️ Subir ⬆️

sql_fetchrow

Código: Seleccionar todo

$db->sql_fetchrow($query_id = false)

Devuelve una fila recuperada por una consulta y mueve el puntero de las filas un lugar para que cuando se vuelva a llamar devuelva la siguiente fila.

Argumentos

Spoiler
Mostrar

$query_id (recurso)

Opcional, por defecto false. El resultado de $db->sql_query() o $db->sql_query_limit() para usar la información de esa consulta. Si es false se utiliza el resultado de la última llamada a $db->sql_query() o $db->sql_query_limit()

Devuelve

Spoiler
Mostrar

Un array con el contenido de una fila recuperada por una consulta.

Ejemplo

Código: Seleccionar todo

$sql = 'SELECT *
    FROM ' . REPORTS_REASONS_TABLE . '
    ORDER BY reason_order ASC';
$result = $db->sql_query($sql);

while ($row = $db->sql_fetchrow($result))
{
    // Mientras sql_fetchrow pueda devolver un resultado y asignarlo a $row el bucle seguirá ejecutándose
    // Normalmente se utiliza esta vía y no sql_fetchrowset ya que permite trabajar con los datos de cada fila en cada iteración
}
$db->sql_freeresult($result);

⬆️ Subir ⬆️

sql_fetchrowset

Código: Seleccionar todo

$db->sql_fetchrowset($query_id = false)

Devuelve todas las filas recuperadas por una consulta.

Argumentos

Spoiler
Mostrar

$query_id (recurso)

Opcional, por defecto false. El resultado de $db->sql_query() o $db->sql_query_limit() para usar la información de esa consulta. Si es false se utiliza el resultado de la última llamada a $db->sql_query() o $db->sql_query_limit()

Devuelve

Spoiler
Mostrar

Un array con todas las filas recuperadas por una consulta.

⬆️ Subir ⬆️

sql_fetchfield

Código: Seleccionar todo

$db->sql_fetchfield($field, $rownum = false, $query_id = false)

Recupera el valor de un campo.

Argumentos

Spoiler
Mostrar

$field (cadena)

El nombre del campo a recuperar.

$rownum (entero)

Opcional, por defecto false. El número de la fila de la que seleccionará el campo (numeradas comenzando desde cero). Si es false se utiliza el valor de la primera fila seleccionada.

$query_id (recurso)

Opcional, por defecto false. El resultado de $db->sql_query() o $db->sql_query_limit() para usar la información de esa consulta. Si es false se utiliza el resultado de la última llamada a $db->sql_query() o $db->sql_query_limit()

Devuelve

Spoiler
Mostrar

El valor del campo recuperado o false si el campo no existe o está vacío.

Ejemplo

Código: Seleccionar todo

// con las funciones agregadas (como COUNT) se utiliza un alias que luego puede ser recuperado con sql_fetchfield
$sql = 'SELECT COUNT(attach_id) as num_attachments
    FROM ' . ATTACHMENTS_TABLE . "
    WHERE poster_id = $user_id
        AND is_orphan = 0";
        
// normalmente solo se necesita una fila para utilizar sql_fetchfield por lo que a veces se utiliza sql_query_limit
$result = $db->sql_query_limit($sql, 1);
$num_attachments = (int) $db->sql_fetchfield('num_attachments');
$db->sql_freeresult($result);

⬆️ Subir ⬆️

sql_nextid

Código: Seleccionar todo

$db->sql_nextid()

Recupera el ID de una columna AUTO_INCREMENT tras insertar un dato en la tabla.

Argumentos

No tiene.

Devuelve

Spoiler
Mostrar

El ID del último campo de una columna AUTO_INCREMENT agregada en la consulta previa en caso de éxito, 0 si la consulta no genera un valor AUTO_INCREMENT, o false en caso de error.

Ejemplo

Código: Seleccionar todo

$sql = 'INSERT INTO ' . TOPICS_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary);
$db->sql_query($sql);

$to_topic_id = $db->sql_nextid();

⬆️ Subir ⬆️

sql_escape

Código: Seleccionar todo

$db->sql_escape($msg)

Escapa una cadena para ser usada con seguridad en una consulta.

Argumentos

Spoiler
Mostrar

$msg (cadena)

La cadena a escapar.

Devuelve

Spoiler
Mostrar

La cadena escapada.

Ejemplo

Código: Seleccionar todo

// como lo que se escapan son cadenas y estas deben estar entrecomilladas siempre en las consultas
// es necesario añadirlas antes y después de usar sql_escape

$sql = 'UPDATE ' . CONFIG_TABLE . "
    SET config_value = '0'
    WHERE config_name = 'cron_lock' 
        AND config_value = '" . $db->sql_escape(CRON_ID) . "'";
$db->sql_query($sql);

⬆️ Subir ⬆️

sql_build_array

Código: Seleccionar todo

$db->sql_build_array($query, $assoc_ary = false)

Prepara un array para ser utilizado en distintas operaciones.

Argumentos

Spoiler
Mostrar

$query (cadena)

La operación para la que se prepara el array. Puede ser: INSERT, INSERT_SELECT, UPDATE o SELECT

$assoc_ary (array)

El array con los datos a preparar.

Devuelve

Spoiler
Mostrar

Una cadena con el contenido del array preparado para la operación dada.

Ejemplo

Código: Seleccionar todo

// array de prueba
$sql_ary = array(
'user_id'    => 2,
'friend'    => 1,
);

$sql = 'SELECT *
    FROM ' . ZEBRA_TABLE . '
    WHERE ' . $db->sql_build_array('SELECT', $sql_ary);
// el valor de $sql es: SELECT * FROM phpbb_zebra WHERE user_id = 2 AND friend = 1
   
// array de prueba
$sql_ary = array(
'user_id'    => 2,
'zebra_id'    => 3,
'friend'    => 1,
);

$sql = 'INSERT INTO ' . ZEBRA_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary);
// el valor de $sql es: INSERT INTO phpbb_zebra (user_id, zebra_id, friend) VALUES (2, 3, 1)

// array de prueba
$sql_ary = array(
'user_id'    => 2,
'friend'    => 1,
);

$sql = 'UPDATE ' . USERS_TABLE . '
    SET ' . $db->sql_build_array('UPDATE', $sql_ary) . '
    WHERE user_id = ' . $user->data['user_id'];
// el valor de $sql es: UPDATE phpbb_users SET user_id = 2, friend = 1 WHERE user_id = 2

⬆️ Subir ⬆️

sql_in_set

Código: Seleccionar todo

$db->sql_in_set($field, $array, $negate = false, $allow_empty_set = false)

Construye una expresión IN o NOT IN con la información de un array. Si el array solo tiene un elemento se convierte en una comparación simple.

Argumentos

Spoiler
Mostrar

$field (cadena)

El nombre de la columna que se utilizará en la comparación.

$array (array)

El array con los valores a utilizar.

$negate (booleano)

Opcional, por defecto false. Si es true se creará una expresión NOT IN.

$allow_empty_set (booleano)

Opcional, por defecto false. Si es true permite que el array esté vacío, y si es así devolverá 1=1, o 1=0 si $negate es true.

Devuelve

Spoiler
Mostrar

Una cadena con la expresión IN o NOT IN preparada.

Ejemplo

Código: Seleccionar todo

// un array de muestra
$user_id = array(2, 4, 6, 13, 16, 65);

$sql = 'SELECT *
    FROM ' . USERS_TABLE . '
    WHERE ' . $db->sql_in_set('user_id', $user_id);
// el valor de $sql es: SELECT * FROM phpbb_users WHERE user_id IN (2, 4, 6, 13, 16, 65)

$sql = 'SELECT *
    FROM ' . USERS_TABLE . '
    WHERE ' . $db->sql_in_set('user_id', $user_id, true);
// el valor de $sql es: SELECT * FROM phpbb_users WHERE user_id NOT IN (2, 4, 6, 13, 16, 65)

// si el array solo contiene un elemento se convierte a una comparación simple 
$user_id = array(2);

$sql = 'SELECT *
    FROM ' . USERS_TABLE . '
    WHERE ' . $db->sql_in_set('user_id', $user_id);
// el valor de $sql es: SELECT * FROM phpbb_users WHERE user_id = 2

$sql = 'SELECT *
    FROM ' . USERS_TABLE . '
    WHERE ' . $db->sql_in_set('user_id', $user_id, true);
// el valor de $sql es: SELECT * FROM phpbb_users WHERE user_id <> 2
// nótese que en lugar de != se usa <> en la consulta ya que este último es el operador estándar

⬆️ Subir ⬆️

sql_multi_insert

Código: Seleccionar todo

$db->sql_multi_insert($table, &$sql_ary)

Permite añadir múltiples filas a una tabla con una sola operación.

Argumentos

Spoiler
Mostrar

$table (cadena)

El nombre de la tabla donde se añadirán los datos.

$sql_ary (array)

Un array multidimencional con los datos a añadir.

Devuelve

Spoiler
Mostrar

True en caso de éxito o false en caso de error.

Ejemplo

Código: Seleccionar todo

$zebra_array = array();

$zebra_array[] = array(
    'user_id'    => 2,
    'zebra_id'    => 3,
    'friend'    => 1,
    'foe'        => 0,
);

$zebra_array[] = array(
    'user_id'    => 2,
    'zebra_id'    => 4,
    'friend'    => 0,
    'foe'        => 1,
);

$db->sql_multi_insert(ZEBRA_TABLE, $zebra_array);
// la consulta generada es: INSERT INTO phpbb_zebra (user_id, zebra_id, friend, foe) VALUES (2, 3, 1, 0), (2, 4, 0, 1)

⬆️ Subir ⬆️

sql_build_query

Código: Seleccionar todo

$db->sql_build_query($query, $array)

Construye una consulta SQL desde un array.

Argumentos

Spoiler
Mostrar

$query (cadena)

La operación para la que se prepara el array. Puede ser: SELECT o SELECT_DISTINCT

$array (array)

Un array asociativo con los datos con que se construirá la consulta.

Devuelve

Spoiler
Mostrar

La consulta preparada.

Ejemplo

Código: Seleccionar todo

// Cada elemento del array forma parte de la consulta, este ejemplo es bastante completo
$sql_array = array(
    'SELECT'    => 'm.*, u.user_colour, g.group_colour, g.group_type',

    'FROM'        => array(
        MODERATOR_CACHE_TABLE    => 'm',
    ),

    'LEFT_JOIN'    => array(
        array(
            'FROM'    => array(USERS_TABLE => 'u'),
            'ON'    => 'm.user_id = u.user_id',
        ),
        array(
            'FROM'    => array(GROUPS_TABLE => 'g'),
            'ON'    => 'm.group_id = g.group_id',
        ),
    ),

    'WHERE'        => 'm.display_on_index = 1',
);
$sql = $db->sql_build_query('SELECT', $sql_array);

// El valor de $sql es: 
SELECT m.*, u.user_colour, g.group_colour, g.group_type 
    FROM (phpbb_moderator_cache m) 
LEFT JOIN phpbb_users u 
    ON (m.user_id = u.user_id) 
LEFT JOIN phpbb_groups g 
    ON (m.group_id = g.group_id)
 WHERE m.display_on_index = 1
 // La indentación y los saltos de línea son para apreciar mejor la sentencia, la generada solo ocupa una línea

⬆️ Subir ⬆️

sql_affectedrows

Código: Seleccionar todo

$db->sql_affectedrows()

Devuelve las filas afectadas por la última consulta SQL.

Argumentos

No tiene.

Devuelve

Spoiler
Mostrar

Las filas afectadas por la última consulta SQL.

⬆️ Subir ⬆️

sql_freeresult

Código: Seleccionar todo

$db->sql_freeresult($query_id = false)

Elimina de la memoria el resultado de $db->sql_query() o $db->sql_query_limit()

Argumentos

Spoiler
Mostrar

$query_id (recurso)

Opcional, por defecto false. El resultado de $db->sql_query() o $db->sql_query_limit() para liberarlo. Si es false se utiliza el resultado de la última llamada a $db->sql_query() o $db->sql_query_limit()

Devuelve

Spoiler
Mostrar

True en caso de éxito o false en caso de error.

⬆️ Subir ⬆️

sql_error

Código: Seleccionar todo

$db->sql_error($sql = '')

Muestra una pantalla de error SQL.

Argumentos

Spoiler
Mostrar

$sql (cadena)

Opcional, un comando SQL que se mostrará junto al error.

Devuelve

Spoiler
Mostrar

No devuelve ningún valor.

⬆️ Subir ⬆️