miércoles, 3 de diciembre de 2014

Convertir columna NULL en columna NOT NULL


1. EL PROBLEMA

Parece una tontería (y en el fondo, lo es), pero esta mañana me he enfrentado a la necesidad de tener que cambiar el diseño de una tabla para especificar la restricción sobre una columna, que inicialmente podía contener valores nulos, para que fuera una columna NOT NULL. Coser y cantar, me he dicho... Pero no. La cosa se ha complicado un poco.

Figura 1. Situación de partida: actualmente la columna id_concurso puede ser NULL. Queremos cambiar esto

Antes de nada, habrá que rellenar de datos esta columna, para asegurarnos de que no hay ningún registro con NULL en ese campo. Esto es de cajón (no puedo indicar que sea NOT NULL una columna que contiene datos NULL), así que asumimos que esto ya lo hemos hecho (por ejemplo, se pueden actualizar todos los NULL a un valor especial como cero o un número negativo).


2. PRIMER INTENTO: EL DISEÑADOR GRÁFICO DE TABLAS

Como la base de datos está en una instancia de SQL Server, en primer lugar, he intentado hacer el cambio desde la interfaz gráfica del SQL Server 2008 Management Studio, la herramienta oficial de administración de bases de datos de Microsoft, asumiendo que la cosa iba a ser cosa de desmarcar el checkbox y guardar.

Figura 2. Desmarcar el checkbox de "Permitir valores NULL" y ya está. ¿O no?

Pero... cuando lo he intentado, ¡mi gozo en un pozo!

Figura 3. Mensaje de error. No se puede hacer desde la interfaz gráfica. ¡OMG!


3. SEGUNDO INTENTO: DDL

Bueno. No es la primera vez que esta herramienta, el Management Studio, me da estos disgustos. A veces impide hacer cosas desde la interfaz gráfica (como alterar la PRIMARY KEY) pero me permite hacerlas escribiendo la correspondiente instrucción DDL en una ventana de consulta. Así que intentaré hacerlo así.

Después de intentar recordar (sin éxito, mi memoria no da para mucho) la sintaxis de la instrucción ALTER TABLE para hacer esto, me he tenido que lanzar a una búsqueda en Internet, asumiendo que lo iba a encontrar en menos de un minuto. Pero...

... buscando... buscando... buscando...

...tras unos minutos dando vueltas, me encuentro con que aparentemente NO se puede hacer en un único paso (ah, quizás mi memoria no era tan mala después de todo). Aquí tenéis una explicación (en inglés) de cómo se puede hacer para Firebird, pero imagino que el proceso puede valer para cualquier otro motor de BD. Básicamente, los pasos son:

1. Crear una nueva columna NOT NULL
2. Rellenar de datos esta columna con los datos de la columna original
3. Eliminar la columna original
4. Renombrar la columna nueva con el nombre de la columna original

OJO: si lo miráis en el ejemplo de Firebird que os he enlazado, la sintaxis que allí aparece no es válida para SQL Server (no sé si es que con Firebird vale, o es que directamente han cometido algún error sintáctico).

Se entiende, ¿no?

Ok, manos a la obra.


Paso 1. Crear nueva columna temporal

Al ejecutar la primera instrucción, obtengo el mensaje de error siguiente:

Figura 4. Mensaje de error. No puedo crear una columna NOT NULL. 

Claro, qué despiste. Si crea una columna nueva NOT NULL, ¿qué valores le asignaríamos a los registros existentes en esa columna? Así que tendremos que especificar un valor DEFAULT para esos registros, dejando la instrucción así (esto no lo tuvieron en cuenta en el ejemplo del Firebird)

1. ALTER TABLE mitabla ADD columna_nueva INTEGER NOT NULL DEFAULT 0


Figura 5. Ahora sí: nueva columna no nula creada. Datos por defecto a 0 (cero)


Paso 2. Rellenar los datos

Figura 6. Actualizar el nuevo campo a partir del antiguo. Sin problemas


Paso 3. Eliminar la columna original

Figura 7. Eliminar columna


Paso 4. Renombrar la columna

Figura 8. Vaya, la sintaxis en SQL Server no es 'RENAME COLUMN'.

Un par de consultas al patito y veo que en SQL Server, para renombrar una columna de una tabla, hay que usar el procedimiento sp_rename,

Figura 9. Renombrar una columna con sp_rename. ¿Por qué no me funciona?

Bueno, como veréis en la figura 9, no me ha funcionado, seguramente por algún error de sintaxis. Me he vuelto loco probando distintas maneras: con comillas sencillas, con comillas dobles, con el nombre simple de la tabla, con el nombre de la tabla totalmente cualificado (precedido de esquema y propietario)... y no he conseguido ejecutar el sp_rename. Lo que sí he comprobado es que con el diseñador, en la interfaz gráfica, sí que te deja modificar el nombre de la columna, así que he optado por esa opción, la fácil. Pero agradecería si alguien me sabe decir por qué no me ha funcionado ninguna de las opciones anteriores.

Figura 10. Podemos renombrar la columna desde la vista Diseño de la tabla


4. CONCLUSIÓN

Aunque en principio parece una operación trivial modificar el estatus de una columna de una tabla que acepta valores nulos a la situación en que no los acepta, a la hora de la verdad la cosa se puede complicar un poco.

Como resumen, aquí están los pasos que yo he dado en SQL Server 2008 Management Studio

1. ALTER TABLE mitabla ADD columna_nueva INTEGER NOT NULL DEFAULT 0;
2. UPDATE mitabla SET columna_nueva = columna_original
3. ALTER TABLE mitabla DROP COLUMN columna_original
4. Renombrar 'columna_nueva' a 'columna_original' en el diseñador gráfico

En la explicación en inglés que os he puesto arriba introducen un COMMIT entre los pasos 1 y 2 y otro entre los pasos 2 y 3. Me parece una muy buena idea, aunque os dejo a vosotros el pensar por qué.


EPILOGO

Después de tener esta entrada escrita, encuentro (concretamente, aquí) que hay una forma muuuuuuuucho más simple de hacer lo que yo quería

ALTER TABLE dbo.mitabla ALTER COLUMN columna_original INTEGER NOT NULL

La he probado y funciona perfectamente

Figura 11. ¡Haber empezado por ahí, hombre!


A la vista del resultado, a punto he estado de borrar esta entrada, pero no lo he hecho por varias razones

1) Ilustra un proceso que ocurre muchas veces en informática. Uno se plantea una forma de hacer las cosas, y cuando está cerca del final, descubre otra forma más sencilla de hacerlo. Mi opinión es que no hay que ser nostálgico, no te aferres a "tu" código por el hecho de que tú lo has "parido". Si hay una forma mejor, o más sencilla, tira lo viejo y quédate con lo mejor.

2) En el ejemplo del Firebird que encontré, se indicaba que con ese motor de BD había que hacerlo así, con la secuencia de cuatro pasos que os he puesto arriba. No he probado si también allí funciona la forma "simple", pero si no funciona, habría que usar la "compleja". Lo mismo vale para otros SGBD (Sistemas Gestores de Bases de Datos, o motores).

3) La secuencia de cuatro pasos indicada tiene sentido desde el punto de vista pedagógico, para aquellas personas que están aprendiendo temas de administración de bases de datos.

4) Como digo a veces, el lema de este blog es "Lo explico para enterarme yo". Es decir, si no me hubiera planteado explicar el problema paso a paso, quizás no hubiera encontrado la solución simple. Al menos, queda aquí para mí como una lección aprendida.

5) Y además, ya que la tenía escrita no iba a borrarla, ¿verdad? ;-) (esto es una broma, como digo en el punto 1: "no te aferres, no te aferres...").

viernes, 31 de octubre de 2014

Cómo saber cuánto tiempo lleva encendido el ordenador

A veces queremos saber cuánto tiempo lleva encendido un ordenador. ¿Cómo podemos hacer esto?


Figura 1. ¿Qué hora es en este reloj hebreo? (Visto en Praga)

1. Respuesta corta

En Linux, MacOs, HP-UX y versiones varias de UNIX: comandos "w", "uptime" y "top"

En Windows: comando "systeminfo"


2. Respuesta larga

2.1 Aplicaciones
Simplemente, queremos saber cuánto lleva encendido el equipo. O bien, somos los responsables de un servidor, y queremos saber si el servidor se ha reiniciado por la noche, por ejemplo. O hemos llegado a casa y hemos pillado a nuestro hijo todo viciado matando orcos a diesto y siniesto. A pesar de que le dijimos que sólo podía jugar una hora al día, tiene los ojos inyectados en sangre, rojos como dos tomates, sospechamos algo y no nos creemos lo que nos jura y perjura de que acaba de encenderlo "hace ná". Queremos comprobar, en todos estos casos, cuánto tiempo lleva el ordenador encendido.

2.2 En Linux
Si el equipo está ejecutando un Linux, bastará con teclear bien poco, una sola letra y hecho. El comando "w" nos da la información que queremos en la primera línea de su salida. Como una imagen vale más que mil palabras, ahí va un ejemplo:

Figura 2. Este equipo lleva 4 días, 4 horas y 14 minutos encendido

Tenemos más información adicional en ese comando, pero la que nos interesa está en la primera línea, junto con los datos de carga del procesador en el último minuto, últimos 5 y últimos 15 minutos. Si lo único que queremos es la información de esa primera línea sin mostrar la otra información (la de los usuarios que hay conectados), entonces podemos hacer un grep para solo mostrar la primera línea, así:

$ w | grep "load average"

(ojo, esto podría sacar también otras líneas que contuvieran esa cadena de texto)

O bien, y mejor aún, ejecutar el comando "uptime", que muestra únicamente esa primera línea.

Figura 3. Uptime como un "w" limitado a la primera línea

Otro comando que está en todos los *NIX modernos y que da esta misma info (más un montón de información adicional) es el comando top. Así, si ejecutamos

$ top

Obtendremos algo así

Figura 4. El comando "top" también nos dice cuánto tiempo lleva encendido el ordenador

Aunque a decir verdad, a mí me gusta más la versión de "top con colorines", llamada "htop" (también existen "atop" y otros...)


Figura 5. htop: top con maquillaje de colores

2.3 En Windows
En todas las versiones de Windows desde XP tenemos el comando "systeminfo", que se encarga de recoger un montón de información del equipo, entre ella la que nos interesa. En XP salen tantas líneas que se pierde la información por arriba, y en mi caso, el buffer de la ventana de comandos no conserva todas las líneas cuando vuelvo hacia atrás, así que he tenido que redirigir la salida al comando "less" para que me la muestre paginada

c:\> systeminfo | less

También podríamos haber redirigido esta salida a un fichero de texto y luego abrirlo con el bloc de notas.

Al ejecutar systeminfo, tras unos segundos, durante los cuales vemos unos mensajes indicando qué está haciendo el programa, tenemos una salida tal que así

Figura 6. Salida de "systeminfo" en Windows XP

donde podemos ver que el equipo lleva 4 días y casi 11 horas encendido (penúltima línea de la imagen).


2.4 Mi script personal
Como me gusta la salida en una única línea que proporciona el comando uptime de Linux, me he hecho mi pequeño script en Windows, lo he colocado en la carpeta de utilidades que tengo incluida en el PATH, para poder invocarlo igual que lo hago en Linux. Lo he llamado "uptime.cmd", y su contenido es sencillamente las siguientes dos líneas

Figura 7. Script para implementar un uptime

(el comando "find" es equivalente al grep de Linux)

Y ahora sí, en mi consola de Windows

Figura 8. Uptime disponible también en Windows

Y así no tengo que pensar si estoy en Linux o en Windows, en ambos sitios puedo escribir uptime y respuesta inmediata.

Y ahora pregunto yo...
Dicho todo esto, ¿alguien sabe cómo ver en un smartphone con Android el tiempo que lleva funcionando desde el último reinicio? Seguramente no sea muy complicado, pero le he dedicado unos minutos y no he hallado la respuesta rápidamente. Voy a seguir buscando.

Ahí queda la pregunta


lunes, 20 de octubre de 2014

Validación de documentos (X)HTML

Si recordáis la entrada de hace unos días (enlace abajo) hablaba del Principio de Robustez de Postel. Y decía que los navegadores suelen aplicarlo siendo muy transigentes con lo que aceptan como entrada en las páginas web. Aunque una página no se ajuste exactamente a la especificación HTML correspondiente, normalmente los navegadores hacen todo lo que pueden por mostrar una vista "razonable" de la página.

Pero que ellos sean permisivos no quiere decir que los desarrolladores nos debamos relajar. Tenemos que intentar que nuestras páginas sean lo más ajustadas posible a la especificación. Para ello, podemos usar los validadores proporcionados por el W3C u otras instituciones. Exigirnos a nosotros mismos hacer páginas estrictas se corresponde con la parte "be conservative" del principio (ver la entrada anterior, enlace abajo).

Para ello, podemos entrar en el validador del W3C, en la dirección http://validator.w3.org/, y ahí podemos poner la URL de una página web que queramos validar. Por ejemplo, vamos a probar la página principal de la CARM. Introducimos su URL y pulsamos "Check"

Y en este caso vemos que la página valida perfectamente respecto al esquema XHTML 1.0 Transitional. El validador del W3C ha accedido a la página que le hemos dicho y ha leído su contenido y lo ha contrastado con respecto a la especificación.



VALIDACIÓN LOCAL

Pero, ¿qué pasa si queremos validar una página local a la que el W3C no puede acceder, ya que no tiene acceso a nuestra intranet? Por ejemplo, una página principal del servidor web que tengo instalado en mi equipo para hacer pruebas. En este caso, el W3C nos dice que no puede acceder a esta página, por no ser pública


Esto también ocurre con algunas páginas que utilizan HTTPS en vez de HTTP.

Lo que sí podemos hacer es usar otra opción existente en el validador, bastante útil, y que consiste en pegar directamente el código HTML que queremos validar en un cuadro de texto. Para esto,

  1. Abrimos en un navegador la página web que queremos validar y mostramos su código fuente y lo copiamos al portapapeles. Para ver el código fuente de la página, en los principales navegadores hay que pulsar Ctrl + U. Si quieres hacerlo por menú, en Firefox está en Herramientas / Desarrollador web / Código fuente de la página, y en Chrome está en Herramientas / Ver código fuente.
  2. Pulsamos sobre la pestaña "Validate by Direct Input" y pegamos ahí el código de la página a validar
  3. Pulsamos Check



Espero que en vuestras páginas no salga el mensaje de error, y os diga que todo está chachi piruli (en mi caso no ha sido así, ¡glups!)


ICONOS DE VALIDACIÓN

Una vez validada nuestra página, "tenemos permiso" para poner un icono que indique que la página se ha validado con respecto a tal o cual esquema (HTML 4, XHTML 1, CSS 3...).




Esto sirve para informar a nuestros visitantes de que nos hemos tomado la molestia de intentar ser un poco exigentes con respecto a la sintaxis y gramática de nuestra página. No es todo lo que hay que hacer en una página, pero al menos es un paso en la dirección correcta. Yo me he encontrado muchas veces estos iconos de validación en páginas de ciertas organizaciones, como por ejemplo algunas páginas de la Universidad de Murcia, como el Portal único de acceso (aunque no en la página principal [!]).



Esto significa que en algún momento, el desarrollador correspondiente validó la página y el resultado fue positivo. Sin embargo, se ve que después han hecho algunos cambios en la página y se les ha olvidado volver a validarla, pues si pruebo a validarla por mí mismo obtengo este resultado



donde vemos que la página tiene algunos errores de validación.

Así que ya sabéis, si validáis vuestras páginas (sea por URL o por entrada directa, o subiendo un fichero, que también se puede hacer así), no olvidéis revalidarla cuando hagáis algunos cambios de importancia.

Otra cosa importante: si la página a validar contiene datos personales (por ejemplo, una página con resultados de una BD), mi consejo es que no peguéis estos datos directamente en el validador, ya que de esa forma los datos personales estarían saliendo de vuestra organización y llegando (como mínimo) al W3C. No sé si el W3C registra una copia del código que valida, pero por si acaso lo hace, o por si hay alguien "in the middle" escuchando, no es una buena idea. Para esos casos, hay instrucciones en la web del validador sobre cómo se puede instalar una copia en un equipo local, donde podéis validar todas las páginas de datos que queráis. Si alguno lo prueba, estaré encantado de que nos deje aquí sus comentarios.


MI CASO

En mi caso, he validado algunas páginas realizadas por mí. Y sí, he encontrado errores. Cuando el listado de errores es un poco largo, por un momento te sientes como si fueras un chapucero. ¿Cómo es posible que mi página tenga tantos errores de validación? ¿Debo dejarme el desarrollo y dedicame a criar champiñones? Por suerte, esto es parecido a lo que ocurre con algunos compiladores de C, que a veces corregir el primer error hace que desaparezcan 20 ó 30 errores posteriores, y es que el validador a veces se hace un lío tras el primer contratiempo.

En cualquier caso, no hay nada mejor que conocerse. Así que me ha venido muy bien para conocer mi estilo propio de desarrollo (y corregirlo) el ver cómo la mayoría de mis errores se corresponden con los mismos cuatro o cinco errores recurrentes una y otra vez. Entre ellos, el no poner texto ALT en algunas etiquetas <IMG> (esto puede ser importante por accesibilidad, el atributo ALT es requerido), usar el cierre abreviado de etiquetas (ya sabéis, el />) en etiquetas que no lo admiten, o bien ignorar el atributo "type='text/javascript'" en algunos fragmentos de código JavaScript. Así que una vez corregidos estos pequeños errores, las páginas han validado correctamente y ya he podido poner el "sello" de página validada.

Se quedan en el tintero muchas cosas, como los diferentes esquemas contra los que validar nuestra página, validación de otras cosas que no son HTML, como por ejemplo el CSS, etc... pero eso lo dejo para quien quiera profundizar en el tema. No os lo voy a dar todo masticado, ¿verdad?

¿Y tú? ¿Validas tus páginas? ¿Contra qué esquemas? ¿Usas otro validador distinto del que proporciona el W3C (sí, hay otros)? ¿Has descubierto si metes mucho la pata en tus páginas?


ENTRADAS RELACIONADAS

Sé conservador, sé liberal...be water, my friend
http://cosicasdeinformatica.blogspot.com.es/2014/09/se-conservador-se-liberalbe-water-my.html


REFERENCIAS

¿De qué va todo eso de la validación? (en inglés)
http://validator.w3.org/docs/help.html#validation_basics

lunes, 29 de septiembre de 2014

Sé conservador, sé liberal...be water, my friend

Una vez conocí en la universidad a una chica extranjera que hablaba español bastante bien, aunque de vez en cuando tenía algún fallo. Le gustaba que le corrigiéramos sus fallos hasta en lo más insignificante. Si se enteraba de que le habíamos pasado un error sin corregir, nos presionaba para que la próxima vez no lo hiciéramos. Estaba empeñada en aprender hasta sus últimas consecuencias, aunque esto implicara hacer muchas interrupciones en la conversación.

- El bicicleta se me ha rrrroto
- Te puedo prestar la mía
- ¿"La mía"? ¿Bicicleta es un sustantivo femenino?
- Estooooo... sí
- ¡¡Y porrr qué no me lo has corrrregido??
- Bueno, te he entendido, no me pareció una cosa tan importante
- Sí lo essss. Te tengo dicho que no me pases ni uno
- De acuerdo. Se dice que "no me pases ni una"
- Grrrasssias
- Se dice "gracias"
- ¡Grrrmmppfff!

Sin saberlo, esta chica estaba aplicando en el ámbito de la filología una versión particular de la "Ley de Postel".

El Principio de Robustez

Jon Postel (Juanito para los amiguetes) fue un informático estadounidense, de los de la vieja escuela (nació en 1943 el buen hombre), que hizo muchas aportaciones a las tecnologías de Internet durante el nacimiento y los primeros años de la Red. Por algo lo llegaron a llamar "El Dios de Internet". Así, como suena, os lo aseguro. La verdad es que si vemos su foto, sí que se parece un poco a esa imagen un poco ñoña de dios como un viejecito con cara de buena persona con barba blanca (un amigo mío dice que le recuerda a David el Gnomo).

Fuente: Wikipedia, por el usuario Tedder
http://en.wikipedia.org/wiki/Jon_Postel#mediaviewer/File:Jon_Postel_sitting_in_office.jpg

Entre otras cosas, Postel fue el editor de numerosos documentos técnicos relacionados con estándares. Ya sabéis que los informáticos nos ponemos cachondos con las siglas, así que a estos documentos los llamaron RFC (Request For Comments). En concreto, el RFC 760 (si eres masoca, abajo tienes el enlace, aunque ya te aviso de que quedó obsoleto por documentos posteriores), especificaba lo relativo al protocolo TCP/IP, ya sabéis, una minucia sin importancia (con decir que prácticamente TODAS las comunicaciones en Internet se basan en él, ¡ahí es ná!). En ese RFC, Postel enunció, allá por enero de 1980, una frase famosa que pasó a la historia con su nombre. La "Ley de Postel" (o Principio de Robustez, que también se le llama así) viene a decir que "una implementación debería ser conservadora en lo que envía, y liberal al procesar lo que recibe" (traducción libre mía). También se ha enunciado a veces como "Sé liberal con lo que aceptas, sé conservador con lo que envías". Después de decir esta frase, Juanito se sentó con las manos cruzadas en su regazo, como lo véis en la foto.

En realidad, he mirado en el RFC 760 y este es el texto exacto del original en inglés (así podéis haceros vuestra propia traducción):

        3.2. Discussion

          The implementation of a protocol must be robust.  Each implementation
          must expect to interoperate with others created by different
          individuals.  While the goal of this specification is to be explicit
          about the protocol there is the possibility of differing
          interpretations.  In general, an implementation should be conservative
          in its sending behavior, and liberal in its receiving behavior
.  That
          is, it should be careful to send well-formed datagrams, but should
          accept any datagram that it can interpret (e.g., not object to
          technical errors where the meaning is still clear).


De acuerdo, pero... ¿qué significa esto? Pues básicamente, que cuando uno produzca datos de salida que vayan a ser procesados por otros, intentar que estos datos se ajusten al máximo a las normas, que se sea todo lo estricto posible. Pero, por el contrario, a la hora de recibir y procesar datos de entrada, aceptar estos aunque presenten algún defecto menor que no afecte a la posible interpretación (es decir, que no se descarten unos datos por un defecto "de forma", como se anulaban antes algunas multas). O dicho más llanamente, sé muy quisquilloso con lo que produces, y sé muy permisivo con lo que producen los demás.

O como dice mi amiga la Jenny, "me lo trago tó".


Un ejemplo

Por ejemplo, si estoy esperando un color en formato hexadecimal para el fondo de una página web, y el diseñador ha escrito algo como

bgcolor=#AABBCC

pues su intención está clara. Quiere pintar el fondo de la página de ese color tirando a grisáceo (desde luego, hijo, qué soso). Sin embargo, para cumplir con la especificación oficial, el color debería estar entrecomillado, ya sea con comillas simples o dobles, así

bgcolor='#AABBCC'

Un programa que se encuentre el color como en el primer caso, sin las comillas, puede hacer varias cosas. Una de ellas (si fuera quisquilloso con lo que recibe, que es LO CONTRARIO de lo que recomienda Postel) es dar un mensaje diciendo que la página no es correcta, informar de ello y no mostrar la página. Vaya, qué programa tan exigente, ¿verdad?

Un programa más "enrollao", al leer la primera línea, entiende lo que se quiere decir, aunque falten las comillas. Si aplica la ley de Postel, ese programa debería interpretar el color como si el usuario hubiera introducido bien los datos, con el color entrecomillado. Como dice Postel, "...no poner objeciones a errores técnicos si el significado está claro". O sea, vale, no me has puesto las comillas en el color, pero entiendo lo que quieres decir. Pelillos a la mar. Esto sería un ejemplo del "be liberal".

Por otro lado, si ese mismo programa se encarga de generar o enviar datos, debe obligarse a sí mismo a cumplir estrictamente con el estándar, y enviar el código del color con las comillas correspondientes, incluso en el hipotético caso de que supiera que el receptor es capaz de "digerir" los datos sin comillas. Eso no valdría como excusa. Aquí quien manda es la especificación, y nunca se sabe si en una próxima actualización del programa receptor el programador encargado de la misma va a seguir manteniendo el criterio del primer equipo de desarrollo o va a reprogramar la parte encargada de procesar los colores, y entonces puede que algo que haya estando funcionando hasta el momento, de pronto deje de funcionar. Por ello, más vale forzarse uno a generar datos "buenos". Nivel de autoexigencia alto. No nos vamos a detener por unas comillas, ¿verdad? ¿Qué somos, leones o huevones?

Algunos de los mejores ejemplos de programas conservadores-liberales en este sentido lo tenemos en los navegadores más famosos. La mayoría de ellos son capaces de leer una página HTML y, aunque no esté bien formada, puede visualizarla haciendo algunas suposiciones razonables cuando se encuentre errores menores. Hay que tener cuidado, ya que puede que nos navegadores diferentes hagan diferentes suposiciones "razonables" (este concepto a veces es taaaaaan ambiguo...). De hecho, quizás os haya pasado a veces que hayáis comprobado que una página web se visualiza de forma ligeramente distinta en un navegador u otro, ¿verdad? Diferentes mentes, diferentes suposiciones "razonables".

También hay quien advierte de que una aplicación demasiado "tragona" puede poner en riesgo la seguridad precisamente por ese afán por aceptar datos que no sigan los patrones exactos que se esperan de ellos. Algo que también hay que tener en cuenta.

En fin, como resumen, que la ley de Postel viene a ser como una ley del embudo, pero al revés: lo ancho para los demás, lo estrecho para mis programas.

Un aparte


Además, la Ley de Postel es una buena receta para otras facetas de la vida. ¿Os imagináis cómo funcionaría la Sociedad, por ejemplo, si todos fuéramos un poco más transigentes con lo que esperamos de los demás, y fuéramos más estrictos con lo que le damos nosotros al mundo? Normalmente, solemos funcionar al revés.

La estudiante de la que os hablaba al principio es otro buen ejemplo de la parte "be conservative": se exigía hablar perfectamente bien, aunque sabía que podía defenderse y hacerse entender con soltura hablando regular. Pero no, ella tenía un nivel alto de autoexigencia. Be conservative.

Bueno, todo esto lo decía como introducción para hablar sobre el tema de la validación de documentos HTML, pero como esta entrada me está quedando ya un poco larga, hablaré de ello en otra ocasión.

Que ustedes lo codifiquen bien (y conservadoramente ;-)

Y rezadle a Postel.



Referencias

El principio de Robustez, explicado un poco más en detalle
En inglés: http://en.wikipedia.org/wiki/Robustness_principle

El RFC 760, donde se enunció por primera vez este principio
http://tools.ietf.org/html/rfc760

martes, 26 de agosto de 2014

Fotos públicas en Endomondo

Desde principios de año tenía por ahí aparcado y pendiente este tema del que voy a hablar hoy. Hace unas semanas, Chema Alonso publicó esta entrada hablando acerca de algunos problemas de privacidad en Endomondo (lectura muy recomendada), así que me he decidido a publicar lo que yo había experimentado, que viene a ser un dato más que añadir a lo que él cuenta allí. Como dicen los abogados: "...a mayor abundamiento..."

El caso es que cuando salgo a correr o a pedalear, suelo utilizar la aplicación Endomondo para registrar mis "proezas". Me gusta esta aplicación, ya que luego puedo entrar en la página web y revisar mis prácticas, exportar el fichero GPX con la ruta, ver estadísticas, etc...



Una de mis "proezas". Como véis, estoy hecho un espartano (¡aug!).

Pues bien, me encontraba yo revisando mis prácticas en el navegador cuando se me ocurrió hacer clic en mi imagen de perfil. Esto hizo que se me abriera una ventana aparte con la imagen



Sí, es la misma foto que tengo en mi perfil de Google+, y en varios sitios más. Original que es uno

Hmmm... Supongo que ya os habréis dado cuenta, ¿no? Aquí hay algo que pinta raro. ¿Las imágenes tienen una URL fija? No se accede a ellas a través de un script que valide la sesión del usuario. A ver, voy a cambiar algún dígito de la URL de mi foto de perfil, a ver qué sale...



Vaya, un vecino de URL

Parece ser que Endomondo no exige nada para que puedas ver la foto de perfil más allá de saberte la URL. Siendo esto así, a cualquier novato con un conocimiento mínimo de programación no le costaría nada hacer un pequeño script que con wget se fuera descargando imágenes, una tras otra, "a ver qué sale". Sería más o menos algo como esto:


 1 #!/bin/bash
 2 
 3 desde=1
 4 hasta=100
 5 ruta1=http://image.endomondo.com/resources/gfx/picture/
 6 ruta2=/big.jpg
 7 
 8 i=$desde
 9 while [ $i -le $hasta ]; do
10     echo "descargando $ruta1$i$ruta2"
11     wget $ruta1$i$ruta2 -O big.$i.jpg
12     let i=$i+1
13 done 
14 
El script para Linux. La adaptación a Windows es fácil, pero quien la quiera tendrá que hacérsela 

Como se puede ver, he elegido un rango pequeño de perfiles, del 1 al 100, por poner un ejemplo, pero se podrían modificar estos límites a voluntad y explorar qué fotos hay por ahí. Muchas fotos de esos perfiles no existen, y muchas otras contienen elementos donde la privacidad no es relevante (¿por qué a tanta gente le gusta poner la foto de su bici de montaña?), pero hay otras donde se ve gente acompañada de otra gente, con sus niños, etc...

¿Es esto un problema? Pues depende. Depende, sobre todo, de los términos y condiciones que uno acepta cuando se registra en Endomondo. Así, a priori, antes de leerlos (enseguida los veremos), me parece que no es lo ideal. A mí me parece bien que mis amigos en Endomondo vean mi foto de perfil, pero no que la pueda ver todo el mundo, incluso aquellos que no están registrados en la web.

Si leemos detenidamente la política de privacidad, nos encontramos que nuestra foto de perfil forma parte de nuestros datos personales

Tu foto de perfil forma parte de tu información personal

Y un poco más adelante


vemos que nuestra foto de perfil es pública por defecto, y que CONSENTIMOS en que así sea si no cambiamos la privacidad en nuestra cuenta. Hmmm, no me parece la mejor opción, pero así son las cosas.

¿Puedo cambiar esto en la configuración de la privacidad de mi cuenta? Bueno, más o menos

Tu perfil, o lo ve todo el mundo o los usuarios de Endomondo

En casi todas las opciones (la mayoría de las cuales vienen por defecto con el valor "Todos") se te da la opción de poner "Amigos", para limitar la visibilidad de tus datos, o incluso puedes poner "Sólo yo". Sin embargo, para la opción de mi perfil sólo puedo elegir "Todos" o "Usuarios Endomondo". Vale, lo cambio para que sólo lo puedan ver los usuarios de Endomondo.

Y una vez cambiado, intento ver si tengo acceso a mi foto de perfil poniendo la URL del principio... y el resultado es... ¡se sigue viendo! (he de reconocer que no me sorprende, me lo esperaba).

Conclusión: que tu foto de perfil sigue siendo visible para TODO EL MUNDO, no sólo para los usuarios de Endomondo.

Otra cosa: no soy ningún experto en políticas de privacidad, pero ya que han hecho el esfuerzo de traducir la interfaz al idioma español, ¿no deberían haber hecho lo mismo con la política de privacidad?

Mi consejo: no subas a Endomondo fotos que te interese tener con verdadera privacidad, ya que están accesibles públicamente mientras Endomondo no cambie esto.

¿Y tú, también tienes subida a Endomondo esa foto que no te gusta que todo el mundo vea?

Enlaces relacionados

Endomondo: www.endomondo.com

Róbame que estoy haciendo deporte: http://www.elladodelmal.com/2014/07/robame-que-estoy-haciendo-deporte-y.html

viernes, 25 de julio de 2014

Habilitar las librerías de cifrado de PHP en Ubuntu

Para cifrar (encriptar no existe para la RAE, aunque muchas veces utilicemos ambos verbos como sinónimos) un bloque de datos, en PHP podemos utilizar la función mcrypt_encrypt

Fig. 1. Parámetros de mcrypt_encrypt

El primer parámetro de esta función hace referencia al algoritmo que emplearemos. Pero, ¿qué algoritmos podemos utilizar? Para ver los que hay disponibles en nuestro sistema, podemos utilizar la función mcrypt_list_algorithms. Por ejemplo, así:

 1 <?php
 2 echo "<pre>" . print_r (mcrypt_list_algorithms (), TRUE) . "</pre>";
 3 ?>
Listado 1. ¿Qué algoritmos puedo utilizar para cifrar mis datos?

He probado esto en Windows y la salida ha sido la siguiente:

Figura 2. ¡Hala, qué variedad para elegir! Pito, pito, gorgorito...

Pero, al probar lo mismo en Ubuntu, la salida ha sido...


...




¡absolutamente nada!


Pero... ¿qué está pasando?????


Fig. 2. WTF!!!!!?????

Vale. Tras un poco de surfeo web, parece ser que hay que hacer una receta de 3 pasos:

1) Instalar php5-mcrypt
2) Reiniciar el servidor web
3) Habilitar la extensión mcrypt

Si sabéis hacer esto, podéis dejar de leer ya. Si eres como yo, que no sabía cómo se hacía, aquí están los detalles:

1) Instalar php5-mcrypt

$ sudo apt-get install php5-mcrypt

Como podemos deducir del nombre, hemos de disponer de la versión 5 o superior de PHP. ¿Que cómo sabemos cuál tenemos? Pues así:

$ php -v

Si no tienes la 5 o superior, actualízala (si puedes).


2) Reiniciar Apache

Tienes varias formas. Por ejemplo, así

$ sudo /etc/init.d/apache2 restart

o bien

$ sudo service apache2 restart

Tras esto, aún seguimos sin poder obtener los algoritmos de cifrado ("cifradores" los llama la documentación oficial de PHP) disponibles.


3) Habilitar la extensión en el fichero php.ini

Para ello, se incluye la línea

extension = mcrypt.so

en el fichero de configuración de PHP, el famoso php.ini.

Y ahora ya... ¡sí! Al ejecutar en Ubuntu el script de antes (Listado 1) obtenemos la salida

Figura 3. La misma lista de "cifradores" que en Windows, aunque cambie el orden de algunos elementos

Hala, ya podéis darle un buen uso a las funciones de cifrado.

viernes, 18 de julio de 2014

Cuánto te mide, cariño (Un Programador Honesto e Inteligente [y guapo, sobre todo guapo]) - Parte 4 de 4

(continúa)

PARTE 4 DE 4 (¡POR FIN!)

¿Deberíamos contar las líneas en blanco en un programa como "líneas de código"? ¿Y los comentarios? A priori, todo parece indicar que no. Imaginemos que mi jefe mide mi productividad por el total bruto de líneas de código, incluyendo las líneas en blanco y los comentarios (por fortuna, un jefe que sabe lo que se hace no lo haría sólo así, es una medida muy chapucera). Entonces yo podría insertar deliberadamente líneas en blanco a troche y moche y comentarios innecesarios cada dos por tres con cualquier excusa, "para aumentar la legibilidad" (e intentar conservar mi trabajo hasta que detecten el "truco"). Esto da un argumento a favor de no contar las líneas en blanco ni los comentarios. Así, metas más o menos, da igual. Sólo cuenta el CÓDIGO DE VERDAD.

Sin embargo, es verdad que un par de líneas en blanco insertadas en lugares estratégicos pueden aumentar la legibilidad y comprensibilidad de una rutina, mientras que un código al que le falten esas líneas en blanco o unos comentarios puede ser bastante más difícil de comprender. Respecto a los comentarios, pasa tres cuartos de lo mismo. Bien usados, son un mecanismo útil. Mal usados (abusados, generalmente), son un problema: aumentan la cantidad de lectura, pueden quedar desfasados respecto al código... El debate es antiguo y ha dado (y dará) para ríos de tinta. McConnell lo plantea como una pequeña escenificación parodiando las obras de teatro griegas y los diálogos de Sócrates, en el capítulo 32 de Code Complete (punto 32.2 To Comment or Not To Comment). Es una lectura que os recomiendo, al menos está escrita de una manera "gracioseta".


Figura 1. Un libro sobre desarrollo de software + unos cuantos chistes malo-buenos

En cualquier caso, como decía en la entrada anterior, la utilidad o no de medir estas líneas en blanco y comentarios DEPENDE DEL OBJETIVO. En mi caso, quiero medir MIS proyectos. Es decir, YO soy el medidor y YO soy el padre de la criatura a medir. Por lo tanto, como no me quiero engañar a mí mismo, asumo que el programador que ha creado ese código, aparte de ser guapo a rabiar, tiene dos características importantes para conmigo: es honesto y es inteligente (hola, autoestima, ya sabía yo que no tardarías en salir).


Figura 2. Así se me pone la cara pensando si contar o no las líneas en blanco. Lo sé, me pongo un poco raro cuando pienso, y la Angelina me mira que me quiere comer 

1) Con lo de ser honesto, quiero decir que no va a insertar más líneas en blanco de las que suele insertar en su estilo normal de programación. Tampoco va a meter comentarios de relleno, más allá de los que suele meter habitualmente. Es decir, en los proyectos usa las líneas en blanco y los comentarios como elementos que también forman parte del programa, en su justa medida, como suele hacerlo habitualmente en el resto de los proyectos. Es decir, no va a engañar, ni (mucho menos), a engañarse.

2) Inteligente significa que no abusa de los comentarios, no mete paja... En fin, que los usa bien. Por lo tanto, unos buenos comentarios para mí tienen tanto valor como unas líneas de código. Aquí radica la clave de mi discurso. Para mí, esos comentarios útiles SON PRODUCTIVOS. Incluso esas líneas en blanco. Luego, si al sacar las métricas del proyecto no los tengo en cuenta, estoy descartando un producto de interés. Es verdad que esas líneas no son de interés para el compilador, pero sí son de interés para otro programador, o para mi YO del futuro cuando vuelva a leer ese trozo de código dentro de unos meses. Por lo tanto, esos comentarios (y líneas en blanco correctamente utilizadas) que mejoran la legibilidad y comprensibilidad del código, se deben contar. Aportan valor al código fuente.

Esto, además, tiene el efecto colateral de que simplifica mucho la tarea de contar las líneas de código de mi proyecto. Se limita a contar las líneas que tiene cada fichero de código. Hacer un pequeño programa para esto es trivial. Aunque esto es un efecto secundario, nunca el motivo principal para no excluir esas líneas en blanco y esos comentarios.

Bueno, creo que con esto ya me he explicado lo suficiente. Quizás me he enrollado un poco de más, pero necesitaba dejar esto claro para explicar mis siguientes entradas, en las que llevaré esto de las métricas a un caso práctico, y quería justificar un poco las decisiones tomadas.

Prometo que en la próxima entrada pondré código, que hace tiempo que no se ve por aquí y eso no puede ser.

---
Enlace a la parte 1
http://cosicasdeinformatica.blogspot.com.es/2014/07/cuanto-te-mide-carino-el-proyecto-se.html

Enlace a la parte 2
http://cosicasdeinformatica.blogspot.com.es/2014/07/cuanto-te-mide-carino-no-cuentes-lineas.html

Enlace a la parte 3
http://cosicasdeinformatica.blogspot.com.es/2014/07/cuanto-te-mide-carino-o-tanto-medir-pa.html

martes, 15 de julio de 2014

Cuánto te mide, cariño (o Tanto medir, pa qué) - Parte 3 de 4

(continúa)

PARTE 3 DE 4

Enlace a la parte 1
Enlace a la parte 2

En mi caso, creo que el número de líneas de código, aún con todos sus defectos asociados, es la métrica MÍNIMA IMPRESCINDIBLE que debería incluirse en todo conjunto de métricas de un proyecto. Esto no quiere decir que sea la única que haya que considerar, esta métrica deberá estar complementada y apoyada por algunas otras (tampoco muchas, repito lo de "pocas, pero buenas").

Pero si alguien me dice que no tiene ni idea de las líneas de código del proyecto en el que se está moviendo, algo va mal. Es como si un arquitecto me dijera que está trabajando en un puente y no sabe de cuántos metros es (claro está, redondeando, no le voy a exigir saberlo al milímetro). Yo mismo, en mis primeros años como programador profesional, muchas veces he trabajado en proyectos de los que luego no he sabido describir su tamaño con una medida objetiva. Y no, no me valen cosas como "un proyecto grande", "un proyecto mediano". Eso no me parece propio de un ingeniero. Como ingeniero, te pido que me des algún dato OBJETIVO del proyecto. El número de líneas de código será un dato muy básico, de utilidad muy limitada, pero es OBJETIVO. Todas las métricas han de ser objetivas.



¿Cuáles son mis objetivos al medir el tamaño de mi proyecto?

1. Conocer algún DATO OBJETIVO de él, que pueda ser medido por un tercero sin influencia de factores subjetivos. El número de líneas de código lo es. Da igual que lo mida yo o que lo mida un revisor externo. Otra cosa es que establezcamos condiciones que sean las mismas para todos: si cuentan las líneas de comentario, si cuentan las líneas en blanco, los tipos de archivos que consideraremos (código fuente, ficheros de configuración, páginas HTML estáticas...) y todos los demás detalles. Normalmente, estos dos tipos de líneas, las blancas y las de comentarios, no se suelen contar, aunque yo tengo un criterio diferente en algunos casos, pero de momento no me quiero ir por las ramas. Lo importante es que los criterios estén bien fijados; una vez hecho, la métrica es un valor objetivo.

2. Poder COMPARAR dos proyectos (o más). Al menos, dos proyectos realizados por el mismo programador. Ya he hablado anteriormente de que diferentes programadores significa diferentes estilos de programación, y el mismo programa puede cambiar de "tamaño" según las manos por las que pase. Pero si lo que quiero es comparar dos programas hechos por la misma persona, entonces sí que significa algo el número de líneas de código. O si quiero medir la productividad de un programador a lo largo del tiempo, sí tiene sentido comparar el número de líneas de código que ha producido en diferentes semanas.

3. GESTIONAR LA COMPLEJIDAD, intentando detectar, por ejemplo, variaciones bruscas en el tamaño del proyecto. O intentando reducir el tamaño cuando sea posible sin menoscabo de la funcionalidad (por ejemplo, por hacer una refactorización). Si un lunes extraigo una métrica del proyecto y veo que se mueve por las 50.000 líneas, y al lunes siguiente el proyecto ha pasado a 60.000 líneas, algo significa, ¿no? Habrá que entrar luego en detalles, pero al menos podemos tener un sistema automatizado que nos haga saltar un aviso para después ponernos a bucear en los pormenores del proyecto de manera más refinada. Otro ejemplo: si voy a acometer una fase de refactorización de mi proyecto, sí tiene sentido medir las líneas de código antes y después de la operación, para evaluar de alguna manera de qué nos ha valido (también tendrá otros beneficios aparte de reducir el número de líneas, claro, como una mejor organización del código, una mayor legibilidad, simplificación de uso, etc.).

Curiosamente, cuando he empezado a medir mis proyectos con estos tres únicos objetivos, resulta que después las métricas me han servido para otras cosas. Una vez que tienes datos objetivos, se te ocurren nuevas formas de dotarlos de significado y hacer cosas interesantes con ellos. Es lo que decía al principio: pocas métricas, pero explotándolas a tope.


--
Enlace a la parte 1
Enlace a la parte 2


viernes, 11 de julio de 2014

Cuánto te mide, cariño (no cuentes líneas, cuenta líneas) - Parte 2 de 4

Una de las medidas más básicas del tamaño de un proyecto es contar el número de líneas de código.

Como principal ventaja, tiene que es una medida de las más sencillas de obtener, pero tiene muuuuuuuchos inconvenientes. Algunos de ellos son que no se pueden contar las líneas de aquellos artefactos del proyecto que no se corresponden directamente con texto, como ficheros binarios. Por ejemplo, elaborar un informe en Crystal Report conlleva una cantidad de trabajo y tiempo cuya productividad no se puede cuantificar en líneas de código, ya que este informe es un fichero binario. O elaborar unas plantillas RTF que luego se rellenarán con datos. Aunque el RTF resultante sea texto, probablemente, el número de líneas variará mucho si se elabora con un editor como Word o con el LibreOffice o con el WorPad, ya que el salto de línea probablemente se insertará de manera diferente. Y también variará mucho si se inserta una imagen, que quedará codificada como un chorizo gigante de texto (binario codificado en hexadecimal) incomprensible y que computaría probablemente como una única línea de texto. 

Otro inconveniente importante es que el número de líneas de código es muy dependiente del estilo de programación, es "marca de la casa" del programador. Dos programadores pueden formatear el mismo programa de diferente manera, pueden incluir muchos o pocos comentarios, usar diferentes convenciones para colocar los delimitadores de bloques (llaves {}, palabras clave "begin", "end", "case", "default", y similares), diferentes estilos de sangrado, embellecer el código con más o menos líneas en blanco... 

Y es que ya lo sabemos: todo programador lleva un artista dentro, y no puede evitar que ese artista se le cuele por entre las líneas que teclea y se refleje en el código que produce.

Test para programadores: ¿cuántas líneas de código hay aquí? ¿Pero quién ha programado esto?

Así pues, ¿vale la métrica de líneas de código para medir el esfuerzo de generar esos artefactos binarios, o para medir el tamaño de dos programas escritos con estilos muy diferentes? No, desde luego que no.

Y, sin embargo...

Y sin embargo, los mismos autores que explican por qué no vale el número de líneas de código, cuando cuentan experiencias personales suelen hablar de "...cuando trabajé en un proyecto de 400.000 líneas de código...". Pero bueno, ¿en qué quedamos?

En Code Complete, uno de mis libros preferidos sobre desarrollo de software, Steve McConnell habla varias veces de las líneas de código de un programa cuando quiere dar una idea acerca de su complejidad o tamaño.

En el capítulo 8, hablando de un programa insignificante, de esos que casi seguro que nadie conoce, llamado Microsoft Word (no os suena, ¿verdad?), McConnell dice

"...la aplicación es tan compleja (millones de líneas de código) y ha pasado
 por tantas generaciones..."

Como veis, el autor asume que el número de líneas de código de alguna manera le da al lector una idea de la complejidad de la aplicación. También habla constantemente del número de líneas de código de rutinas para hacer referencia a su complejidad. En el capítulo 11 dice

"...a mediados de 2003 trabajé con un cliente que tenía cientos de miles de 
líneas de código escritas en RPG..."

Y en el capítulo 13, hablando de modularidad,

"...La esencia de la creación de programas mayores que unos cientos 
de líneas de código es la gestión de la complejidad..."

Los ejemplos se repiten, en este y en muchos otros libros, artículos, ponencias, etc, así que no seguiré.

Por supuesto, McConnell es sobradamente consciente de las limitaciones de la métrica de las líneas de código. Pero como vemos, en cierto modo, aunque las líneas de código no sean una medida buena si se considera de manera aislada, tampoco son una medida del todo inútil. De hecho, muchas veces es la única métrica que se cita cuando no hay tiempo para entrar en más detalles. El autor habla como si esa medida, con todos sus inconvenientes, significara algo. ¿Lo significa?

Lo significa.

Y lo sabes (como diría Julito).

O al menos, lo significa para algunos objetivos, y tomándola siempre con las debidas reservas.

(continuará)
--
Enlace a la parte 1.

miércoles, 9 de julio de 2014

Cuánto te mide, cariño (el proyecto, se entiende) - Parte 1 de 4

Un principio básico de cualquier ingeniería es MEDIR (diría incluso que es importante en muchos otros aspectos de la vida, pero no quiero profundizar, que enseguida os da por pensar en lo mismo, golfos). Así pues, medir también es importante en la Ingeniería del Software, pero ¿Cómo mido mi proyecto? ¿Cómo puedo evaluar su tamaño, la productividad del equipo de desarrollo, el esfuerzo? ¿Cómo puedo hacer predicciones basándome en el tamaño? ¿En qué tamaño? Mejor aún, ¿qué es el tamaño, cómo se mide el tamaño?

Medir, medir, medir... ¡Estáis obsesionados!

La teoría sobre las métricas es muy amplia y daría lugar a varios blogs y libros sobre ello. De hecho, existen, podéis buscarlos si estáis interesados (o pinchar aquí si sois muy comodones). Diversos autores han definido literalmente cientos, si no miles, de métricas, ya sea genéricas o específicas, por ejemplo, para sistemas orientados a objetos, para aplicaciones funcionales, de gestión, métricas de calidad, de acoplamiento, de dependencia, de diseño, de programación, de arquitectura, etc...

Sin embargo, es preferible tener un conjunto pequeño de métricas, y sacarles todo el partido posible, que hacer unos informes cojonudos, llenos de gráficas y colorines, con miles de parámetros medidos, y que luego no se tengan en cuenta esos valores calculados para nada. Por eso, métricas sí, pero teniendo claro el objetivo de esas métricas y las acciones a las que van a dar lugar. Es decir, saber cuál es el objetivo de las métricas.

¿Y tú, cómo mides tus proyectos? ¿Qué medidas has encontrado que te son las más útiles durante el desarrollo de tus proyectos? ¿Cuál es el objetivo de esas medidas, para qué las tomas?

(continuará)

miércoles, 11 de junio de 2014

¿Qué día me dijiste que teníamos la reunión? (Manejo de fechas en SQLite3)

Como dicen en la propia documentación de SQLite, en SQLite3 no existe el tipo de datos fecha.

Cito directamente de http://www.sqlite.org/datatype3.html


1.2 Date and Time Datatype

SQLite does not have a storage class set aside for storing dates and/or times. Instead, the built-in Date And Time Functions of SQLite are capable of storing dates and times as TEXT, REAL, or INTEGER values:

    TEXT as ISO8601 strings ("YYYY-MM-DD HH:MM:SS.SSS").
    REAL as Julian day numbers, the number of days since noon in Greenwich on November 24, 4714 B.C. according to the proleptic Gregorian calendar.
    INTEGER as Unix Time, the number of seconds since 1970-01-01 00:00:00 UTC.

Applications can chose to store dates and times in any of these formats and freely convert between formats using the built-in date and time functions.

Así que lo más conveniente es declarar el tipo de ese campo como TEXT (o números, también vale), almacenar las fechas en el formato ISO8601 (básicamente: 'YYYY-MM-DD HH:MM:SS'), así además se puede ordenar por ese campo simplemente ordenando como texto, y utilizar las funciones de fecha de SQLite3 para procesarlas.

Por ejemplo, para hacer una comparación:

 1 select * from tabla where julianday(f1) > julianday('2014-01-01 00:00:00')


 

UN EJEMPLO PRÁCTICO


Bien, hasta aquí la teoría. Vamos a probarlo. Para ello, voy a utilizar SQLite Expert Personal, donde he creado una base de datos y dentro de ella crearé una tabla con un campo fecha.

1. Creamos la tabla

 1 CREATE TABLE PERSONAS
 2 (
 3   ID         NUMBER(10)  NOT NULL,
 4   NOMBRE     VARCHAR(30),
 5   APE1       VARCHAR(30),
 6   APE2       VARCHAR(30),
 7   FNACIM     DATETEXT  
 8 );

El tipo de dato DATETEXT (línea 7) se corresponde internamente en SQLite Expert con WideString, pero en realidad debería valer cualquier tipo de datos de texto.

2. Insertamos unos cuantos datos de ejemplo

 1 insert into PERSONAS(ID, NOMBRE, APE1, APE2, FNACIM) values (1, 'MARIANO', 'RAJOY', 'ZAPATERO', '1965-05-20');
 2 insert into PERSONAS(ID, NOMBRE, APE1, APE2, FNACIM) values (2, 'JOSE LUIS', 'RAJOY', 'ZAPATERO', '1970-06-20');
 3 insert into PERSONAS(ID, NOMBRE, APE1, APE2, FNACIM) values (3, 'PETER', 'SCHWARZENEGGER', NULL, '1973-08-30');
 4 insert into PERSONAS(ID, NOMBRE, APE1, APE2, FNACIM) values (4, 'ARNOLD', 'LANDA', 'CLARK', '1982-08-30');

Antes de consultar nada, comprobamos que los datos se han insertado bien, yéndonos a la pestaña "Data" de SQLite Expert
Fig. 1. Los datos. Cuántos conocidos por aquí.


3. Hacemos una consulta 

En ésta, utilizamos la función "julianday" para comparar fechas

 1 SELECT * FROM PERSONAS WHERE julianday(FNACIM) > julianday('1970-07-01')


El resultado:
Fig. 2. Resultado de la consulta. Los más jovencitos del grupo


Bueno, parece que todo ha ido bien.

Además de juliandate, SQLite incorpora otras cuatro funciones para trabajar con fechas: date, time, datetime y strftime. Os recomiendo la lectura de la página donde se describen (enlace al final).

Una vez que se sabe esta forma de trabajar con las fechas en SQLite3, la cuestión parece una tontería, pero el hecho de que SQLite no tuviera un tipo de dato nativo para las fechas me ha hecho perder un buen rato. Espero que no le pase a quien lea esto.

¿Y tú, te has peleado con fechas en SQLite?

Más info:

SQLite. http://www.sqlite.org/

Funciones de fecha en SQLite. http://www.sqlite.org/lang_datefunc.html

SQLite Expert Personal. Un estupendo gestor de bases de datos SQLite. http://www.sqliteexpert.com/download.html
Related Posts Plugin for WordPress, Blogger...