lunes, 20 de octubre de 2014

Tres formas de crear usuarios en MySQL

El sistema gestor de bases de datos MySQL posee una completa gestión y configuración de permisos y usuarios.

En este nuevo post vamos a ver tres posibilidades de creación de usuarios. El primero y el segundo son los más habituales. El tercero ya es algo extraño de utilizar.

1. Sentencia GRANT

La sentencia GRANT proporciona privilegios y permisos a los usuarios de MySQL. Para poder utilizar esta sentencia el usuario con el que accedas a MySQL debe ser el usuario root o un usuario con privilegios de GRANT OPTION.

Si queremos crear un usuario simplemente lanzamos la siguiente sentencia:

mysql> GRANT ALL ON test.* TO 'testuser'@'localhost' IDENTIFIED BY 'pass_testuser';
Query OK, 0 rows affected (0.05 sec)

Con esta sentencia lo que hemos conseguido es darle todos los permisos a un usuario llamado testuser sobre todas las tablas de la base de datos test, que solamente podrá conectarse a la base de datos desde el ámbito localhost y que tiene un password pass_testuser. Además, si el usuario no existe lo crea. Los privilegios ALL [PRIVILEGES] da todos los permisos excepto el GRANT.

La sentencia GRANT, si encuentra que el usuario no existe lo crea, siempre que el servidor MySQL tenga el parámetro NO_AUTO_CREATE_USER inactivo. Si estuviera activo solamente nos permitiría crear usuarios que no tengan password asignado.

La mayor utilidad de este método es que con una única sentencia creamos el usuario y le damos los permisos.

Si se necesita ampliar la información sobre los permisos lo podéis hacer desde la documentación oficial de MySQL sobre GRANT.

2. Sentencia CREATE USER

Con esta sentencia lo que haremos simplemente será crear un usuario, específicándole el ámbito en el que funcionará y su password.

mysql> CREATE USER 'testuser'@'localhost' IDENTIFIED BY 'pass_testuser';
Query OK, 0 rows affected (0.05 sec)

En esta ocasión no le estaremos dando permisos sobre ninguna base de datos. Lo que estamos haciendo es crear el usuario con permisos para conectarse desde localhost y con un password. Si queremos ahora darle permisos podríamos hacer lo siguiente para conseguir lo mismo que en la sentencia GRANT anterior:

mysql> GRANT ALL ON test.* TO 'testuser'@'localhost';
Query OK, 0 rows affected (0.00 sec)

3. Insert directo sobre la tabla user

Este último sería el método más complicado y que MySQL no recomienda. Se trata de realizar un insert sobre la tabla user de la base de datos mysql.

Lo primero que deberíamos conocer es la estructura de la tabla y para ello nos tenemos que conectar a la base de datos mysql:

mysql> use mysql;
Database changed

mysql> describe user;
+-----------------------+-----------------------------------+------+-----+---------+-------+
| Field                 | Type                              | Null | Key | Default | Extra |
+-----------------------+-----------------------------------+------+-----+---------+-------+
| Host                  | char(60)                          | NO   | PRI |         |       |
| User                  | char(16)                          | NO   | PRI |         |       |
| Password              | varchar(41)                       | NO   |     |         |       |
| Select_priv           | enum('N','Y')                     | NO   |     | N       |       |
| Insert_priv           | enum('N','Y')                     | NO   |     | N       |       |
| Update_priv           | enum('N','Y')                     | NO   |     | N       |       |
| Delete_priv           | enum('N','Y')                     | NO   |     | N       |       |
| Create_priv           | enum('N','Y')                     | NO   |     | N       |       |
| Drop_priv             | enum('N','Y')                     | NO   |     | N       |       |
| Reload_priv           | enum('N','Y')                     | NO   |     | N       |       |
| Shutdown_priv         | enum('N','Y')                     | NO   |     | N       |       |
| Process_priv          | enum('N','Y')                     | NO   |     | N       |       |
| File_priv             | enum('N','Y')                     | NO   |     | N       |       |
| Grant_priv            | enum('N','Y')                     | NO   |     | N       |       |
| References_priv       | enum('N','Y')                     | NO   |     | N       |       |
| Index_priv            | enum('N','Y')                     | NO   |     | N       |       |
| Alter_priv            | enum('N','Y')                     | NO   |     | N       |       |
| Show_db_priv          | enum('N','Y')                     | NO   |     | N       |       |
| Super_priv            | enum('N','Y')                     | NO   |     | N       |       |
| Create_tmp_table_priv | enum('N','Y')                     | NO   |     | N       |       |
| Lock_tables_priv      | enum('N','Y')                     | NO   |     | N       |       |
| Execute_priv          | enum('N','Y')                     | NO   |     | N       |       |
| Repl_slave_priv       | enum('N','Y')                     | NO   |     | N       |       |
| Repl_client_priv      | enum('N','Y')                     | NO   |     | N       |       |
| Create_view_priv      | enum('N','Y')                     | NO   |     | N       |       |
| Show_view_priv        | enum('N','Y')                     | NO   |     | N       |       |
| Create_routine_priv   | enum('N','Y')                     | NO   |     | N       |       |
| Alter_routine_priv    | enum('N','Y')                     | NO   |     | N       |       |
| Create_user_priv      | enum('N','Y')                     | NO   |     | N       |       |
| ssl_type              | enum('','ANY','X509','SPECIFIED') | NO   |     |         |       |
| ssl_cipher            | blob                              | NO   |     | NULL    |       |
| x509_issuer           | blob                              | NO   |     | NULL    |       |
| x509_subject          | blob                              | NO   |     | NULL    |       |
| max_questions         | int(11) unsigned                  | NO   |     | 0       |       |
| max_updates           | int(11) unsigned                  | NO   |     | 0       |       |
| max_connections       | int(11) unsigned                  | NO   |     | 0       |       |
| max_user_connections  | int(11) unsigned                  | NO   |     | 0       |       |
+-----------------------+-----------------------------------+------+-----+---------+-------+
37 rows in set (0.00 sec)

Para a continuación poder realizar el insert de la siguiente forma:

mysql> INSERT INTO user VALUES('localhost','testuser',PASSWORD('pass_testuser'),'Y','Y', 'Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0,0);
Query OK, 1 row affected (0.01 sec)

El último paso que nos falta es refrescar las tablas de permisos de la siguiente forma:

mysql> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.00 sec)

Al igual que en el método anterior de CREATE USER, con esto únicamente creamos el usuario, pero no le estamos dando permisos sobre ninguna base de datos. Deberíamos hacerlo igual que en el punto anterior:

mysql> GRANT ALL ON test.* TO 'testuser'@'localhost';
Query OK, 0 rows affected (0.00 sec)

Espero que les pueda servir de ayuda.

Función row_count de MySQL

La función row_count() de MySQL es una función que devuelve el número de filas afectadas de una serie de sentencias SQL tal y como veremos a continuación. Tiene una funcionalidad similar a mysql_affected_rows() de la API de C.

Según el tipo de sentencias devolverá un valor u otro:
  • Sentencias DDL: devuelve un 0. Esto es aplicable a sentencias como CREATE TABLE o DROP TABLE.
  • Sentencias DML diferentes del SELECT: devuelve el número de filas afectadas. Esto se aplica a las sentencias clásicas de INSERT, UPDATE o DELETE, así como a ALTER TABLE LOAD DATA INFILE.
  • Sentencias SELECT: devuelve un -1 si la sentencia devuelve un conjunto de registros. En caso contrario devuelve el número de registros afectados. Por ejemplo SELECT * FROM tabla devuelve -1, pero si hacemos SELECT * FROM tabla INTO OUTFILE 'fichero' devuelve el número de registros que se han volcado al fichero.
  • En las sentencias REPLACE: devuelve un 2 si el nuevo registro reemplaza el anterior. En este caso devuelve un 2 por la fila eliminada y la nueva.

Os presentamos un ejemplo de uso de esta función:

mysql> INSERT INTO tabla VALUES(1),(2),(3);
Query OK, 3 rows affected (0.00 sec)
Records: 3  Duplicates: 0  Warnings: 0

mysql> SELECT ROW_COUNT();
+-------------+
| ROW_COUNT() |
+-------------+
|           3 |
+-------------+
1 row in set (0.00 sec)

mysql> DELETE FROM tabla WHERE i IN(1,2);
Query OK, 2 rows affected (0.00 sec)

mysql> SELECT ROW_COUNT();
+-------------+
| ROW_COUNT() |
+-------------+
|           2 |
+-------------+
1 row in set (0.00 sec)

Función in_array en Javascript

La función in_array() de PHP comprueba si existe un valor dentro del array y nos devuelve true o false. Esta función no existe en Javascript pero la podemos crear fácilmente.

Tenemos el siguiente array en Javascript:

var arrCiudades = ['Londres', 'París', 'Roma', 'Madrid', 'Moscú'];


Si usásemos el framework JQuery no habría problema ya que ya la lleva implementada y simplemente tendríamos que hacer lo siguiente:

if ($.inArray('Madrid', arrCiudades)){ 
  alert('Encontrada'); 
} else { 
  alert('No encontrada'); 
}


En Javascript lo que hacemos es añadírsela al objeto Array de la siguiente forma:

Array.prototype.in_array = function(){ 
  for (var i in this) { 
    if (this[i] == arguments[0]){ 
      return true; 
    }
  } 
  return false; 
}


Podríamos haber buscado simplemente con el método indexOf() que nos devuelve un -1 si no existe o el índice si sí que encuentra el elemento, pero no funciona con el navegador Internet Explorer 8 y anteriores.

Una vez tenemos esto ya podemos buscar si el elemento existe en el array con la siguiente llamada:

if (arrCiudades.in_array('Madrid')){ 
  alert('Encontrada'); 
} else { 
  alert('No encontrada'); 
}


Espero que les pueda servir.

domingo, 19 de octubre de 2014

Obtener el último registro insertado en una tabla en MySQL

En MySQL tenemos una característica muy común en los campos que hacen de clave primaria que es el AUTO_INCREMENT. Al insertar un registro en una tabla que tenga una clave numérica autoincrementable, es habitual necesitar dicho valor.

Para esto tenemos la función last_insert_id() de MySQL que nos devolverá dicho valor, siempre que estemos en la misma sesión en la que hayamos hecho la inserción.

Veamos un ejemplo claro de su uso con la creación de una tabla vehiculos, otra de conductores y la última que relaciona ambas llamada alquiler_vehiculos.

CREATE TABLE vehiculos(
  id_vehiculo INT NOT NULL AUTO_INCREMENT,
  marca VARCHAR(50) NOT NULL,
  modelo VARCHAR(50) NOT NULL,
  color VARCHAR(50) NOT NULL,
  PRIMARY KEY(id_vehiculo)
);

CREATE TABLE conductores(
  id_conductor INT NOT NULL AUTO_INCREMENT,
  nombre VARCHAR(50) NOT NULL,
  apellidos VARCHAR(50) NOT NULL,
  PRIMARY KEY(id_conductor)
);

CREATE TABLE alquiler_vehiculos(
  id_vehiculo INT NOT NULL,
  id_conductor INT NOT NULL,
  PRIMARY KEY(id_vehiculo, id_conductor)
);


Ahora vamos a insertar registros en la tabla vehiculos. El insert lo podemos hacer de dos formas diferentes obteniendo el mismo resultado. En la primera ponemos un null al campo AUTO_INCREMENT y en la segunda enumeramos los campos omitiendo el primero.

mysql> INSERT INTO vehiculos VALUES (null, 'Ford', 'Focus', 'Negro');
Query OK, 1 row affected (0.28 sec)

mysql> INSERT INTO vehiculos (marca, modelo, color) VALUES ('Ford', 'Focus', 'Negro');
Query OK, 1 row affected (0.28 sec)

En ambos casos podemos recuperar el valor de id_vehiculo con last_insert_id().

mysql> SELECT last_insert_id();
+------------------+
| last_insert_id() |
+------------------+
|                1 |
+------------------+
1 row in set (0.01 sec)

Ahora lo que haremos será lo mismo para los conductores y en ese momento aprovecharemos el resultado de last_insert_id() para insertar el registro del alquiler.

mysql> INSERT INTO conductores (nombre, apellidos) VALUES ('Carlos', 'Martín');
Query OK, 1 row affected (0.00 sec)

mysql> INSERT INTO alquiler_vehiculos VALUES (1, last_insert_id());
Query OK, 1 row affected (0.23 sec)


Si obtenemos los registros de la tabla veremos que nos ha insertado un 1 en el id_conductor.

mysql> SELECT * FROM alquiler_vehiculos;
+-------------+--------------+
| id_vehiculo | id_conductor |
+-------------+--------------+
|           1 |            1 |
+-------------+--------------+
1 row in set (0.00 sec)

Sin embargo, si hacemos un insert múltiple, la función last_insert_id nos dará el id del primer registro insertado.

mysql> INSERT INTO vehiculos (marca, modelo, color) VALUES ('Ford', 'Focus', 'Blanco'), ('BMW', '330D', 'Gris'), ('Honda', 'Accord', 'Negro');
Query OK, 3 rows affected (0.04 sec)
Registros: 3  Duplicados: 0  Peligros: 0

mysql> SELECT last_insert_id();
+------------------+
| last_insert_id() |
+------------------+
|                2 |
+------------------+
1 row in set (0.00 sec)

En este caso, si quisiéramos saber el id del último registro deberíamos combinarlo con la función num_rows() de esta forma.

mysql> SELECT row_count()+last_insert_id()-1;
+--------------------------------+
| row_count()+last_insert_id()-1 |
+--------------------------------+
|                             4 |
+--------------------------------+
1 row in set (0.00 sec)

Espero que os pueda servir de ayuda.

jueves, 16 de octubre de 2014

Convertir la primera letra de un string en mayúsculas en PHP y Javascript

Si necesitamos convertir la primera letra de un string a mayúsculas tenemos una forma muy sencilla en PHP mediante la función directa ucfirst.

$str = 'micadena';
echo ucfirst($str); // Micadena


En cambio con Javascript no tenemos ninguna función directa y la tenemos que crear nosotros.

var str = 'micadena';
str = str[0].toUpperCase() + str.slice(1);
alert(str); // Micadena

Espero que les sirva.

Función nl2br en Javascript

La función nl2br de PHP nos proporciona una utilidad a la hora de recuperar información de la base de datos que se ha guardado con caracteres de salto de línea o break line. Lo que realiza en definitiva es convertir los caracteres \r\n, \n\r, \r y \n por <br> o <br />.

Para realizar esto mismo en Javascript podemos usar la siguiente función:

function nl2br(str, is_xhtml) {
  var breakTag = (is_xhtml || typeof is_xhtml === 'undefined') ? '< br />' : '< br>'; // Eliminar el espacio antes del br

  return (str + '')
    .replace(/([^>\r\n]?)(\r\n|\n\r|\r|\n)/g, '$1' + breakTag + '$2');
}


Fuente:

http://phpjs.org/functions/nl2br/