miércoles, 6 de diciembre de 2017

WP - Diseño Web - Panel de carga (loading panel)


Hola nuevamente. Tratando de manternerme conectado, (y mientras espero a que se termine de instalar SQL Server), en esta ocasión quiero compartirles una forma bastante sencilla de hacer un panel de cargado con CSS y javascript. El panel de cargado usualmente es un componente que se utiliza para invalidar un área determinada de la página web mientras se realiza algún proceso, para evitar que el usuario realice alguna acción dentro de dicha área.

El panel que les mostraré básicamente es un DIV que poseerá un GIF animado como indicador de procesamiento. Este “panel” se superpondrá a otro elemento DIV, que es el área a invalidar.

Primeramente, este es el HTML de la página web:



Obsérvese que el DIV que se desea invalidar es el que posee el ID "area_invalidar". Dentro de este se ha colocado el DIV que servirá de panel de cargado, como primer elemento hijo (ID="panel_carga").

Luego, tenemos el archivo CSS ("estilos.css"):



La parte de mayor interés está marcada entre los comentarios "Clases CSS de interés". Nótese que el DIV que representa el área a invalidar tendrá la propiedad position con el valor relative, mientras que el DIV que será nuestro panel de carga tendrá el valor de absolute. Esto se debe a que queremos indicar que las propiedades de posición y tamaño del DIV panel de carga serán relativas con respecto al DIV área a invalidar. Gracias a ello podemos especificar el ancho y alto del DIV panel de carga como 100%, para indicar que éste ocupará todo el espacio del área a invalidar.

Luego, en la misma clase utilizada para el panel de carga, tenemos la propiedad de opacidad (alpha para Internet Explorer, opacity para Mozilla Firefox y otros), con la cual especificamos la razón o porcentaje de opacidad del panel de cargado. Al combinarla con un color de fondo (background-color) se logra un efecto de oscurecimiento y transparencia sobre el área invalidada. Adicionalmente a ello se coloca una imagen de fondo, que en este caso es un GIF animado, mediante la propiedad background-image, para que muestre al usuario un indicador de que se está realizando alguna clase de procesamiento. La imagen es centrada y aparece solamente una vez, gracias a las propiedades background-position:center y background-repeat:no-repeat, respectivamente.

También se tiene la propiedad z-index, que indica la “altura” o nivel del elemento. Dicha propiedad tiene significado dentro del elemento padre, por lo que tiene influencia para todos los nodos hermanos. El valor por defecto es cero, por lo que al colocar un valor de, por ejemplo, 10, nos aseguramos de que el panel de cargado estará sobre el resto de elementos contenidos en el DIV de área a invalidar.

Finalmente tenemos la propiedad de visibilidad, que le colocamos el valor de hidden, para que el panel de carga aparezca oculto al mostrarse la página.

Por otra parte se tiene el archivo de código fuente de Javascript. El javascript es necesario para realizar el cambio de las propiedades CSS a través de las acciones del usuario.



En este caso, según puede observarse en la página HTML (arriba), al presionar el botón "Enviar" se ejecutará la función procesar, que recibe como parámetro el ID del DIV que sirve de panel de carga. Dicha función básicamente se encarga de mostrar el DIV de carga.

Nótese que para efectos demostrativos, al final de la función se colocó una llamada a la función setTimeout, para que el panel de cargado se oculte después de 5 segundos. En una aplicación web real, el panel debería de ocultarse una vez se haya obtenido alguna respuesta o resultado después del proceso solicitado.

Este es el resultado final, antes de presionar el botón:


Luego de presionar el botón, nótese el aparecimiento del panel de cargado solamente sobre el área a invalidar, que para efectos de este ejemplo corresponde al mismo formulario web:


Finalmente después de 5 segundos se oculta el panel de cargado, gracias al uso de la función SetTimeOut.

Como pueden observar este método es una forma fácil, rápida y directa de crear un panel de cargado DIV, utilizando solamente HTML, CSS y javascript puros.

Les debo el código fuente para descargar, ya que lo dejé en otra computadora que he prestado por el momento.

Saludos.

Publicado originalmente el 13/02/2013, en https://itsouvenirs.wordpress.com/2013/02/13/diseno-web-panel-de-carga-loading-panel/.

WP - Nueva sección: SQL Server Snippets

Saludos. En este día quiero anunciarles que he decidido iniciar una nueva sección, llamada SQL Server Snippets, con el objetivo de no dejar de lado el blog debido a la falta de tiempo, y compartir algunas de las cosas que aprendo día a día en mi trabajo con SQL Server. Esta sección consistirá básicamente en entradas breves con segmentos de código (snippets) generalmente cortos, pero muy útiles e interesantes.

Los invito a ver mi primera entrada de esta sección: Tablas con columna autonumérica

Feliz día.

Publicado originalmente el 09/02/2013, en https://itsouvenirs.wordpress.com/2013/02/09/nueva-seccion-sql-server-snippets/.

domingo, 5 de noviembre de 2017

Importar datos desde Excel en C#



Este es un requerimiento con el que muchas veces nos encontramos: ¿Cómo leer datos desde una hoja de cálculo de Microsoft Excel (o similares), utilizando C#? Bueno, existen muchas herramientas y técnicas en el salvaje internet para leer archivos de Excel, desde utilizar las librerías de objetos para interoperabilidad provistas al instalar Excel, utilizar un proveedor OleDB, hasta crear tu propia librería para manipular los archivos de Excel, que después de todo, solo son conjuntos de archivos XML comprimidos con una extensión especial (al menos desde Office 2007).

Sin embargo, mi forma preferida de hacerlo desde hace un par de años, ha sido utilizar la librería EPPlus, que es una librería de código abierto creada por Jan Källman, que provee una API amigable y avanzada para la manipulación de archivos con el formato Office Open XML. Esta librería, publicada bajo la licencia GNU Lesser General Public License, provee funcionalidades que van desde acceder a las celdas de las hojas de cálculo, hasta crear gráficos y tablas dinámicas, así como protección y encriptación de documentos.

EPPlus no necesita librerías de interoperabilidad, ni posee otras dependencias aparte del .NET Framework. Esto permite distribuir la librería como parte de nuestro proyecto, sin requerir la instalación de componentes de terceros. Y lo mejor de todo: está disponible como un paquete de NuGet. Gracias a ello, solo basta con buscar el paquete EPPlus desde el administrador de paquetes de NuGet de Visual Studio, e instalarlo en nuestro proyecto, para hace uso de la librería.

Supongamos por ejemplo que se desea leer un archivo de Excel que contiene en la primera hoja un listado de productos, con los datos Código, Nombre y Precio en las columnas A, B y C, respectivamente. Por simplicidad, asumiremos que todos los productos poseen todos los datos, y que finalizaremos la lectura al alcanzar la primera fila cuyo valor en la columna A esté en blanco. También tendremos en consideración que la primera fila de la hoja posee los encabezados de las columnas. Tendríamos algo así:


Nuestro objetivo será hacer una aplicación de consola sencilla, que lea el listado de productos, y los muestre en la línea de comandos. Para ello, creamos una nueva aplicación de consola de .NET Framework, desde Visual Studio, e instalamos el paquete EPPlus:


Luego, importamos el espacio de nombres OfficeOpenXml, provisto por el paquete EPPlus para el acceso a los archivos de Excel, y System.IO, para la lectura de archivos desde el disco duro. Luego, se procede a escribir el código en el método Main de la clase Program. A continuación se muestra el código fuente final, en el que se explica paso a paso a través de los comentarios el proceso para la lectura del archivo:


El resultado de ejecutar el programa anterior, con el archivo de Excel mostrado, es el siguiente:


Cabe mencionar que el archivo de Excel no debe estar abierto, para poder ser leído. De lo contrario, la aplicación lanzará una excepción al intentarlo leer.

Espero que este ejemplo les haya sido de utilidad, y que se animen a utilizar EPPlus como una alternativa para la manipulación de hojas de cálculo. Que tengan un feliz día.

viernes, 3 de noviembre de 2017

Complementos del navegador para pruebas automatizadas - SideeX


Saludos, en esta ocasión quería compartirles acerca de una herramienta que puede ser de ayuda para la creación de pruebas automatizadas utilizando Selenium: SideeX.

SideeX es, según su sitio web, una versión extendida del Selenium IDE (no sabía que existía hasta la semana pasada :P), el cual es una herramienta del tipo grabar-repetir para la generación de conjuntos de pruebas de UI (Interfaz de usuario) utilizando Selenium. Es extendida debido a que posee funcionalidades adicionales a las de Selenium IDE, y ha sido adoptada oficialmente por el SeleniumHQ como punto de partida para las siguientes versiones de Selenium IDE. Adicionalmente, no solo está disponible como extensión para Firefox, sino también para Google Chrome.

Tomando como ejemplo la versión de Google Chrome, para instalarlo basta con instalarlo en el navegador desde el respectivo enlace (https://chrome.google.com/webstore/detail/sideex-an-extended-versio/nefadabeoagfkgmkgegmjgdhegbllple), presionando el botón Agregar a Chrome.


La versión instalada durante la escritura de esta entrada es la v2.3.0. Una vez instalado, el botón con el logo de SideeX aparecerá en la parte superior derecha del navegador. Dicho botón sirve para iniciar la extensión.



Crearemos un caso de pruebas sencillo para ver SideeX en acción. Para ello, accederemos a la página de inicio de sesión de pruebas del artículo anterior: http://www.phptravels.net/admin

Una vez allí, presionamos el botón de SideeX, para iniciar la extensión. Ello nos despliega la ventana principal de SideeX.


Con ello, podemos proceder a grabar nuestro primer caso de pruebas, presionando el botón Record (Grabar), ubicado en la parte superior izquierda de la ventana de SideeX.


Inmediatamente procedemos a realizar nosotros mismos los pasos de la prueba que deseamos realizar en la página de login. Por ejemplo:

1. Hacer clic sobre la caja de texto del correo electrónico. Nótese como se van registrando los pasos en la tabla de comandos de SideeX. Para este primer paso se registran dos comandos: Abrir la página web, y hacer clic sobre la caja de texto del correo electrónico.


2. Digitar el correo electrónico.
3. Cambiar a la caja de texto de la contraseña y digitarla. En este caso se observará que no se registró comando de clic, debido a que el cambio a la siguiente caja de texto se hizo presionando el botón de tabulación.
4. Hacer clic sobre el botón Login.

Por simplicidad dejaremos el caso de pruebas hasta acá. Para detener la grabación, basta con presionar el botón Stop en la ventana de SideeX.


Para reproducir el caso de pruebas, basta con presionar el botón PlayThisCase. Se observará como SideeX reporduce los pasos grabados en el navegador, mostrando en la tabla de comandos el paso ejecutado, y pintando de verde las filas cuya ejecución fue exitosa. También, en la parte inferior irá apareciendo la bitácora de las acciones ejecutadas.


Para guardar la colección de pruebas que contiene el caso creado, en la lista de TEST CASE ubicada al lado izquierdo de la ventana, se hace clic derecho sobre Untitled Test Suite, y se selecciona la opción Save Test Suite As... 


Luego, solo basta con elegir la ubicación donde se desea guardar, y el nombre del archivo.



Cabe notar que el archivo generado es un HTML, el cual contiene la descripción del conjunto de pruebas y los casos grabados, y puede ser visualizado desde cualquier navegador.


Esto es todo por el momento, para mostrar las características generales de SideeX. En ogtra oportunidad intentaré explorar más a fondo la creación de conjuntos de pruebas, con verificación de datos y todo eso, utilizando esta herramienta.

Ejemplo de aplicación web C# con ServiceStack, MongoDB y AngularJS

En esta ocasión quería compartir una aplicación web de prueba que hice hace casi 3 años. Fue una de mis primeras aplicaciones de tipo SPA (Single Page Application), y mi primer encuentro con las 3 tecnologías mencionadas, por lo que puede que tenga algunas inconsistencias. Sin embargo, podría dar una idea básica del uso de ServiceStack 3.9.71 con C#, AngularJS 1.2.16 y MongoDB (no recuerdo qué versión :P). El ejemplo fue hecho con Visual Studio 2012, usando el .NET Framework 4.5.

Este es el enlace del repositorio: https://github.com/guillegr123/sampletraders

¡Saludos, que Dios les bendiga!

domingo, 22 de octubre de 2017

Tutorial de Vue.js 2 - 1. Qué es Vue.js y preparación del entorno


Índice:

Hola, este es un pequeño tutorial acerca de Vue.js 2 (que espero sí pase de la primera entrega, a diferencia de mis intentos fallidos con Symfony 2 - que por cierto ya van por la v3 - y WebAPI 2 - que por cierto ya esta siendo sustituida por ASP.NET Core 2). La idea de este tutorial surgió como una forma de práctica, después de seguir el tutorial Build a To-Do App with Vue.js 2 de Jeremy Kithome en scotch.io, y para compartir acerca del framework en español.

En esta primera entrega se explicará un poco acerca de qué es Vue.js, y cómo preparar el entorno de desarrollo utilizando Node JS y la herramienta de línea de comandos provista por el framework.

Sin más que agregar, ¡empecemos!

¿Qué es Vue.js?

Vue (pronunciado viú) es un framework progresivo para construir interfaces de usuario utilizando HTML, CSS y Javascript. Es progresivo porque ha sido diseñado para ser adoptado de forma gradual, siendo posible integrarlo con otras librerías en proyectos existentes. Este framework ha sido influenciado desde sus inicios por AngularJS (Angular 1); sin embargo, es más liviano que este, y que otras alternativas similares.

Preparación del entorno de desarrollo

Aunque Vue no depende de ningún framework o herramienta de terceros, y puede codificarse usando cualquier editor de texto, para este tutorial se hará uso de Node JS y la herramienta Vue CLI para la creación del "esqueleto" de la aplicación y su ejecución, y Visual Studio Code con una extensión para el soporte de los componentes de Vue, para la codificación.

Primeramente, se procede a instalar Node JS. Para ello, se recomienda descargar e instalar la versión LTS desde el sitio web oficial (6.11.4 con NPM 3.10.10), para el sistema operativo que se esté utilizando: https://nodejs.org/es/download/

Una vez instalado Node JS, procedemos a instalar la herramienta Vue CLI, que provee un conjunto de plantillas para la creación rápida de aplicaciones. También facilita su ejecución con recarga en caliente, y su compilación para ambiente de producción. Para instalar la herramienta se ejecuta en una terminal el siguiente comando:

npm install -g vue-cli

Para verificar que Vue CLI ha sido instalado correctamente, ejecutamos el comando vue en la línea de comandos, lo cual nos muestra las opciones de uso disponibles:


Luego, con respecto a la edición del codigo fuente, se procede a descargar e instalar Visual Studio Code. La última versión del editor puede descargarse en el siguiente enlace, para el sistema operativo que se esté utilizando: https://code.visualstudio.com/download

Finalmente, para facilitar la edición de los componentes de Vue, buscamos e instalamos "Vetur" en las extensiones de Visual Studio Code.



Vetur es un conjunto de herramientas para trabajar con Vue, que incluye un servidor de lenguaje para VS Code, y provee las funcionaliedades de embellecimiento de código, revisión se errores, auto-completamiento, depuración, entre otras.

Con esto ya se tiene un entorno listo para el desarrollo de nuestra primera aplicación con Vue. En la próxima entrada explicaré como crear el proyecto a partir de la plantilla de webpack, ejecutarlo, y agregar las primeras funcionalidades básicas.

Ir a Parte 2: Creación de proyecto desde plantilla

sábado, 26 de agosto de 2017

Crear un proyecto de pruebas con Visual Studio y Selenium


Saludos. Esta entrada es un tutorial acerca de cómo crear un proyecto de pruebas en Visual Studio utilizando Selenium (por si el título que dice casi lo mismo no es lo suficientemente claro - comentario sarcástico para mí mismo).

¿Qué es Selenium?

Selenium es un conjunto de herramientas de automatización para navegadores, que permite programar y ejecutar pruebas repetitivas para aplicaciones web.

Creación del proyecto y adición de Selenium

El tutorial se ha realizado utilizando Visual Studio Community Edition 2017, y C#. Los pasos para crear el proyecto y ejecutar una prueba de ejemplo se describen a continuación:

El primer paso es abrir Visual Studio, y crear un nuevo proyecto de pruebas unitarias, a través del menú Archivo > Nuevo > Proyecto, y seleccionando la plantilla Proyecto de Prueba Unitaria (.NET Framework), ubicada en las plantillas instaladas bajo la categoría Visual C# > Prueba.


Luego de ello, se procede a agregar los paquetes de Selenium en la solución. Para ello, se abre el panel del Explorador de soluciones, se da clic derecho sobre el proyecto, y se selecciona la opción Administrar paquetes NuGet.


Esto despliega en pantalla el administrador de paquetes NuGet para el proyecto seleccionado. En él se selecciona la opción Examinar, y se procede a realizar la búsqueda de paquetes con la palabra Selenium.


De la lista obtenida, procedemos a instalar los paquetes Selenium.WebDriver (publicado por Selenium Committers) y Selenium.Support (también publicado por Selenium Committers). Estos paquetes incluyen soporte para los navegadores Internet Explorer y Firefox. Para soportar el navegador Google Chrome, es necesario instalar un paquete que lo contenga, como por ejemplo Selenium.Chrome.WebDriver publicado por jbaranda, el cual incluye el ejecutable del driver en la carpeta bin respectiva del proyecto luego de compilarlo.

Una vez descargados e instalados los paquetes ya estamos listos para realizar nuestra primera prueba.

Primera prueba con Selenium

Para nuestra primera prueba, haremos uso de un formulario de inicio de sesión de un sitio de web de demostración llamado PHPTravels, en la URL http://www.phptravels.net/admin

Para ello, abrimos la clase creada al momento de crear el proyecto (por defecto es llamada UnitTest1), y agregamos las referencias para Selenium:

Luego, agregamos el siguiente método de ayuda para poder verificar si un elemento existe en la página web:

Finalmente sustituimos el método de prueba vacío, que fue creado por defecto, y creamos uno nuevo, llamado InicioSesion_ConCredencialesIncorrectas_MuestraAviso que consistirá en probar que si intentamos iniciar sesión ingresando credenciales incorrectas, se nos mostrará en pantalla una notificación indicando el error. El código final de la clase, con el nuevo método, es el siguiente:

Nota: El código fuente completo se encuentra disponible en GitHub: https://github.com/guillegr123/PruebaSelenium

Ejecutando la prueba unitaria

Para ejecutar la prueba unitaria, seleccionamos el nombre del método a probar, damos clic derecho, y seleccionamos la opción Ejecutar pruebas.


Esto abre el panel de Exploador de pruebas, y procede a ejecutar la prueba de forma automatizada, utilizando el navegador Google Chrome, elegido a través del driver utilizado. Se podrá observar como el navegador es abierto, y los pasos descritos en la prueba son ejecutados uno a uno, culminando con la verificación de que el elemento de notificación fue creado.


Una vez culminada la prueba, el resultado de esta es mostrado en el panel del Explorador de pruebas, con un ícono verde en caso de éxito, y uno rojo en caso de fallo.


viernes, 25 de agosto de 2017

Mi primera aplicación móvil


Hola a todos. Quería compartirles un vídeo que re-encontré hace poco, de mi primera aplicación móvil, que hice alrdedor del año 2013 (ya me sentí viejo). En esos tiempos tenía casi nulo conocimiento de Android, y del funcionamiento de aplicaciones móviles en general, por lo que decidí hacerla con Phonegap, ya que me permitía utilizar tecnologías que ya tenía algo de tiempo de conocer y siempre me han gustado.

La aplicación fue hecha para unos amigos que querían iniciar un negocio proporcionando un sistema en el que pequeños negocios se pudieran anunciar, publicar sus eventos, menús, etc., y que el público pudiera verlos a través de una aplicación móvil. El diseño y los íconos fueron proporcionados por ellos.

La aplicación en sí fue construida utilizando AppFramework de Intel (posiblemente la versión 1, no recuerdo), que era un framework para Javascript que utilizaba el patrón MVC, proveía una versión liviana de JQuery (jqLite), y Dot.js para la renderización de las vistas. Adicionalmente incluía componentes que emulaban los controles nativos de iOS.

La aplicación mostrada en el vídeo fue una de las versiones iniciales de la aplicación, en la que aún no había incluido el diseño elegido para la página de los negocios, y en la que el menú lateral era delgado. Este fue sustituido posteriormente por un menú más amplio, que incluía los títulos de las páginas en lugar de solo los íconos.

Fue una experiencia interesante que me permitió conocer y experimentar la creación de APIs web, y la forma en que estas interactuaban con las aplicaciones móviles. De hecho, mi primer servicio web y aplicación fue realizado para este proyecto.

Otros datos interesantes son:
  • La aplicación fue desarrollada principalmente en entorno Linux, con el fin de utilizar herramientas gratuitas pero poderosas, como el lenguaje de programación PHP, el IDE Netbeans, y el gestor de bases de datos MySQL; pero también debido a que la computadora no tenía los recursos suficientes para correr el emulador de Android en Windows, y este corría de forma más eficiente en Linux. Adicionalmente, la versión de Linux que utilizaba era Manjaro (mi primera experiencia con una distro basada en Arch Linux), con el entorno OpenBox, lo que la hacía significativamente más rápida y liviana que Windows y muchas versiones de Linux.
  • El vídeo fue grabado con una herramienta cuyo nombre no recuerdo, pero que irónicamente no poseía interfaz gráfica.
  • La ventana del emulador fue posicionada sobre la vista previa de una imagen de un teléfono celular, ajustada al tamaño del emulador, para que pareciera que el emulador tenía un skin de teléfono celular.
A continuación el vídeo:


jueves, 24 de agosto de 2017

Instalar SBT en Linux


Saludos. En esta entrada explicaré como instalar la Scala Build Tool en Linux. Los pasos los describo a continuación:
  1. Descargar la última versión de SBT desde la página de descargas oficial: http://www.scala-sbt.org/download.html
  2. Descomprimir el paquete descargado. Para efectos de este mini-tutorial, se descargó la versión 1.0.0 en paquete TGZ, y por cuestiones de orden, se descomprimirá en el folder /opt, por lo que en este caso los comandos a ejecutar son:

    $ su        # Iniciar sesión en modo súper usuario
    # mkdir sbt      # Crear directorio sbt, para colocar acá todas las versiones de SBT
    # cd sbt         # Navegar al directorio sbt
    # tar -xvzf /home/usuario/Downloads/sbt-1.0.0.tgz    # Descomprimir el paquete
  3. Hacer que el script sbt sea ejecutable:

    # chmod u+x sbt-1.0.0/bin/sbt
  4. Crear la variable de ambiente SBT_HOME, y agregar la ruta que contiene el script sbt a la variable de ambiente PATH. Para ello, se agrega al final del archivo ~/.bash_profile las siguientes líneas (para establecer las variables para terminales bash para el usuario actual):

    export SBT_HOME="/opt/sbt/sbt-1.0.0"
    export PATH="${PATH}:${SBT_HOME}/bin"
  5. Cerrar sesión e iniciar sesión nuevamente, para cargar las nuevas variables de entorno. Luego de ello, podemos abrir la terminal, y ejecutar el comando sbt, el cual ya estará disponible.

sábado, 19 de agosto de 2017

Desactualizando paquete de Arch Linux sin pacman


A.K.A. El fin de semana después del día que ingenuamente quise actualizar Arch Linux por partes en vez de actualizarlo todo.

Acerca de como comenzó todo

Pueden omitir esta sección. Todo comenzó un día que quise actualizar mi instalación de Apricity OS mientras estaba cenando, pero no quise actualizar todo debido a que necesitaba trabajar en la computadora después de cena, en Windows, y el tamaño de la actualización era de 1.2 Gb, por lo que con una magnífica conexión de 2Mbps, eso iba a tomar un largo rato.

Así que decidí a actualizar solo algunos paquetes que yo creía que eran independientes de todo lo demás. Empecé a ver la lista, y poco a poco fui actualizando algunos paquetes: geany, gimp, nano, samba... curl. Luego de eso seguí usando la computadora por un rato con normalidad, y la apagué. Todo bien.

Luego vine el fin de semana a querer utilizar la computadora para ver vídeos en Youtube mientras desayunaba. Para mis ratos de ocio prefiero ocupar Linux, ya que es más rápido, y no dependo de nada de Windows para ello. Todo bien. Luego noté que Variety no estaba corriendo (Variety se ha vuelto mi referencia de la salud del sistema operativo últimamente). ¡Qué raro?, pensé yo, pues lo había actualizado recientemente. Así que lo ejecuté desde la línea de comandos, para obtener más información. Apareció en pantalla un error de que no se podía encontrar la librería libssl.so.1.1.

Pensé que podría ser que Variety necesitaba otra actualización, así que procedí a actualizar la base de datos de paquetes de pacman, para ver si habían actualizaciones disponibles, con el comando:

sudo pacman -Syy

Cuando veo un error similar: No se puede encontrar la librería libssl.so.1.1. Así que ni modo, recurrí a Google para buscar alguna respuesta.

Después de un rato encontré un post que sugería crear enlaces simbólicos de las librerías requeridas hacia las librerías existentes, así que cree dos enlaces simbólicos, uno para libssl.so.1.1 y otro para libcrypto.so.1.1:

ln -s /usr/lib/libssl.so.1.0.0 /usr/lib/libssl.so.1.1
ln -s /usr/lib/libcrypto.so.1.0.0 /usr/lib/libcrypto.so.1.1

Luego intenté nuevamente actualizar la lista de paquetes de pacman, y obtuve el siguiente error:


Y allí me acordé: había actualizado curl, pero lo que no sabía es que curl requería versiones actualizadas de libssl y libcrypto. Además, lo había actualizado por sí solo pensando que yo había sido el que había instalado el paquete y que no había dependencias de este.  Pero para mi horror, el mismísimo pacman dependía de curl.

Intenté buscar una forma de desactualizar curl, pero la forma estándar requería usar pacman, lo cual fue imposible. Oh, el horror.


Así que ni modo, a buscar una alternativa para hacer la actualización a pata. Gracias a Dios me encontré con esta entrada en Reddit: Pacman libcritpto.so.1.1 errors.

Desactualizando paquete de Arch sin pacman

Sabiendo que en mi caso el error había sido solamente con curl, procedí a realizar la desinstalación de la versión más nueva que encontré en /var/cache/pacman/pkg, la cual era curl-7.55.1-1. Ejecuté el siguiente comando, como super usuario:

tar -tf /var/cache/pacman/pkg/curl-7.55.1-1-x86_64.pkg.tar.xz | sed s:^:/: | grep -v /$ | xargs rm

Explicando el comando por partes:
PasoComandoDescripción
1 tar -tf /var/cache/pacman/pkg/curl-7.55.1-1-x86_64.pkg.tar.xz
Obtiene la lista de archivos contenidos en el paquete.
2 sed s:^:/:
Agrega / al principio de la ruta de cada archivo.
3 grep -v /$
Del listado anterior, quita los elementos que terminen en /, ya que estos corresponden a carpetas.
4 xargs rm
Elimina los archivos listados.

Luego, procedí a instalar la versión previa disponible en el cache de paquetes, que era curl-7.52.1-2, con el siguiente comando (siempre como usuario root):

tar -xf /var/cache/pacman/pkg/curl-7.52.1-2-x86_64.pkg.tar.xz

Y finalmente probé actualizar nuevamente la base de datos de pacman, y todo resultó bien:


Lección aprendida: No actualizar Arch Linux a medias.

sábado, 12 de agosto de 2017

Obtener documentación de base de datos SQL Server

Por cuestiones de tiempo, esta entrada es solo un "dump" de código fuente. Asumiendo que hiciste tu tarea de colocar los comentarios de los objetos de la base de datos utilizando la propiedad extendida MS_Description, a continuación incluyo unas consultas para obtener la documentación respectiva de los objetos más relevantes de la base de datos.

Esquemas

SELECT
  s.name AS esquema,
  ep.value AS descripcion
FROM sys.schemas s
  left join sys.extended_properties ep
    ON s.schema_id = ep.major_id
      AND ep.name = 'MS_Description'
WHERE s.name NOT IN (
  -- Lista de esquemas a ignorar
  'db_accessadmin',
  'db_backupoperator',
  'db_datareader',
  'db_datawriter',
  'db_ddladmin',
  'db_denydatareader',
  'db_denydatawriter',
  'db_owner',
  'db_securityadmin',
  'guest',
  'INFORMATION_SCHEMA',
  'sys'
)
ORDER BY 1

Tablas

SELECT
  SCHEMA_NAME(schema_id) esquema,
  t.name AS tabla,
  ep.value AS descripcion
FROM sys.tables AS t
  left join sys.extended_properties ep
    ON t.object_id = ep.major_id
      AND 0 = ep.minor_id
      AND ep.name = 'MS_Description'
ORDER BY 1, t.name

Columnas

Nota: No he descubierto aún por qué, pero hay ciertos casos en los que la columna que es llave primaria me aparece duplicada. Cualquier ayuda es bienvenida :)

SELECT
  SCHEMA_NAME(schema_id) + '.' + t.name AS tabla,
  c.name AS columna,
  TYPE_NAME(c.system_type_id) AS tipo_de_datos,
  CASE c.max_length
    WHEN -1 THEN 'MAX'
    ELSE CAST(c.max_length AS VARCHAR(100))
  END tamano,
  CASE c.is_nullable
    WHEN 1 THEN 'Sí'
    ELSE 'No'
  END AS permite_nulos,
  CASE i.is_primary_key
    WHEN 1 THEN 'Sí'
    ELSE 'No'
  END AS llave_primaria,
  CASE
    WHEN fk.referenced_column_id IS NOT NULL THEN 'Sí'
    ELSE 'No'
  END AS llave_foranea,
  ep.value AS descripcion
FROM sys.tables AS t
  INNER JOIN sys.columns c
    ON t.object_id = c.object_id
  LEFT JOIN sys.index_columns AS ic
    ON ic.OBJECT_ID = c.OBJECT_ID AND ic.column_id = c.column_id
  LEFT JOIN sys.indexes AS i
    ON i.OBJECT_ID = ic.OBJECT_ID AND i.index_id = ic.index_id
  LEFT JOIN sys.foreign_key_columns AS fk
    ON fk.parent_object_id = c.object_id
      AND fk.parent_column_id = c.column_id
  LEFT JOIN sys.extended_properties ep
    ON t.object_id = ep.major_id
      AND c.column_id = ep.minor_id
      AND ep.name = 'MS_Description'
ORDER BY 1, c.column_id

Llaves foráneas

Nota: Esta consulta devuelve una fila por columna, por lo que aparecerán tantas filas como columnas incluya la llave.

SELECT
  SCHEMA_NAME(t.schema_id) + '.' + t.name as tabla_hija,
  c.name as tabla_hija_columna,
  SCHEMA_NAME(tr.schema_id) + '.' + tr.name tabla_padre,
  cr.name tabla_padre_columna,
  fk.name fk_nombre,
  CASE fk.update_referential_action
    WHEN 0 THEN 'NO ACTION'
    WHEN 1 THEN 'CASCADE'
    WHEN 2 THEN 'SET NULL'
    WHEN 3 THEN 'SET DEFAULT'
  END regla_actualizacion,
  CASE fk.delete_referential_action
    WHEN 0 THEN 'NO ACTION'
    WHEN 1 THEN 'CASCADE'
    WHEN 2 THEN 'SET NULL'
    WHEN 3 THEN 'SET DEFAULT'
  END regla_eliminacion
FROM sys.foreign_key_columns as fkc
  INNER JOIN sys.foreign_keys fk
    ON fkc.constraint_object_id = fk.object_id
  INNER JOIN sys.tables as t
    ON fkc.parent_object_id = t.object_id
  INNER JOIN sys.columns as c
    ON fkc.parent_object_id = c.object_id
      and fkc.parent_column_id = c.column_id
  INNER JOIN sys.tables as tr
    ON fkc.referenced_object_id = tr.object_id
  INNER JOIN sys.columns as cr
    ON fkc.referenced_object_id = cr.object_id
      and fkc.referenced_column_id = cr.column_id
ORDER BY 1, fkc.constraint_column_id

Índices

Nota: Esta consulta devuelve una fila por índice, y muestra las columnas separadas por comas.

SELECT DISTINCT
  da.tabla AS tabla,
  i.name AS indice,
  da.tipo AS tipo,
  CASE i.is_primary_key
    WHEN 1 THEN 'Sí'
    ELSE 'No'
  END AS llave_primaria,
  CASE i.is_unique
    WHEN 1 THEN 'Sí'
    ELSE 'No'
  END AS llave_unica,
  CASE i.is_unique_constraint
    WHEN 1 THEN 'Sí'
    ELSE 'No'
  END AS restriccion_unicidad,
  LEFT(cols.names, LEN(cols.names) - 1) columnas
FROM sys.tables AS t
  INNER JOIN sys.columns c
    ON t.object_id = c.object_id
  INNER JOIN sys.index_columns AS ic
    ON ic.OBJECT_ID = c.OBJECT_ID AND ic.column_id = c.column_id
  INNER JOIN sys.indexes AS i
    ON i.OBJECT_ID = ic.OBJECT_ID AND i.index_id = ic.index_id
  CROSS APPLY (
    SELECT
      SCHEMA_NAME(schema_id) + '.' + t.name tabla,
      CASE i.index_id
        WHEN 1 THEN 'CLUSTERED'
        ELSE 'NONCLUSTERED'
      END AS tipo
  ) da
  CROSS APPLY (
    SELECT c_i.name + ','
    FROM sys.columns c_i
      INNER JOIN sys.index_columns AS ic_i
        ON ic_i.OBJECT_ID = c_i.OBJECT_ID AND ic_i.column_id = c_i.column_id
    WHERE i.OBJECT_ID = ic_i.OBJECT_ID AND i.index_id = ic_i.index_id
    FOR XML PATH ('')
  ) cols(names)
ORDER BY 1, 2, 3

Sobreviviendo a un OS descontinuado - Apricity OS


Saludos a todos, ya tenía un largo tiempo de no escribir en el blog, debido a algunos proyectos que han consumido demasiada parte de mi tiempo libre :(

Precisamente debido a esto, ya que los proyectos habían sido desarrollados en en Windows (Visual Studio, .NET, y todas esas cosas del imperio), ya tenía un  largo rato de no utilizar el sistema Linux que también tengo instalado en mi computadora personal. Pues bien, esta mañana finalmente encendí mi computadora e ingresé a mi muy apreciada instalación de Apricity OS, y como primera tarea decidí que quería hacer funcionar el administrador de fondos de escritorio que tengo instalado, llamado Variety, ya que la ultima vez que entré al sistema habia notado que este había dejado de funcionar y que no podría ser iniciado. Intente ejecutarlo desde la línea de comandos, para obtener más información acerca del posible error, y vi un mensaje que me indicaba que la razón por la cual no estaba funcionando era que la versión de Variety que tenía instalada era antigua, y que debía actualizar a la versión más reciente. Yo le temo a las actualizaciones, pues tienden a romper cosas, en Windows y Linux, pero bueno, era solo un paquete, así que procedí a la actualización usando la confiable herramienta pacman.

sudo pacman -S variety

Pero tristemente no se pudo, ya que en su lugar me apareció el siguiente mensaje:


Siendo un noob en Linux, y en particular en Arch, me puse a investigar en google, y de lo que logré encontrar, decidí que tal vez necesitaba actualizar las bases de datos de los repositorios, así que intenté eso:

sudo pacman -Syy

Y luego me apareció un mensaje más claro:


Falló la descarga del archivo 'apricity-core.db' desde static.aprictyoscom : Falló la conexión a static.apricityoscom puerto 80: Conexión rechazada

La triste sorpresa

Mmm, ¿será tal vez que el servidor no está disponible?
¿Habrá algún espejo para poder usar?
¿Será que iban a hacer mantenimiento de sus servidores este día?
 Bueno, a googlear para buscar alguna noticia. Y allí fue cuando, para mi sorpresa, me dí cuenta de la triste noticia: Apricity OS ha sido descontinuado, desde el 6 de mayo del presente 2017. Ingresando a su página de Github, se puede ver el siguiente mensaje:


¿Apricity OS?

La noticia es triste para mí, ya que Apricity OS había sido mi versión favorita de Linux, desde que empecé a ocupar Linux. Apricity OS era una distro basada en Arch Linux, que intentaba ofrecer lo mejor de este sistema operativo de un forma amigable y sencilla. Entre las cosas buenas que tenía era que oseía un instalador gráfico para facilitar la instalación y actualización de paquetes. También compartía el modelo de actualización de liberación continua de Arch, lo que permitía actualizar el sistema sin tener que instalarlo desde cero nuevamente cada vez que hubiera una nueva versión. Otra característica interesante es que incluía ICE, que es una aplicación que permite utilizar auna aplicación web como si fuera una aplicación de escritorio normal. También poseía una interfaz con un diseño limpio y moderno utilizando Gnome 3.



¿Y ahora qué?

La verdad es que a mí me encanta este sistema operativo, sigue siendo el que más me ha gustado, y considero que siendo basado en Arch, aún puedo continuar utilizándolo, ya que buena parte de los paquetes provienen de ese entorno. Bajo esta premisa, mi siguiente paso fue desactivar el repositorio de Apricity OS de la configuración de pacman. Para ello abrí el archivo /etc/pacman.conf en un editor de texto con el usuario administrador (en mi caso utilicé el comando gksudo geany /etc/pacman.conf para ello). Luego marqué como comentarios las siguientes líneas:

[apricity-core]
SigLevel = Required
Server = http://static.apricityos.com/apricity-core-signed/

Así:

#[apricity-core]
#SigLevel = Required
#Server = http://static.apricityos.com/apricity-core-signed/

Con ello pacman ignora el repositorio de Apricity OS, lo cual evita que se produzca el fallo debido a que no puede descargar su base de datos. Hecho esto ya pude actualizar el paquete que necesitaba.

Conclusiones finales

Es una triste noticia que un sistema operativo tan eficiente, elegante y amigable haya llegado a su fin, en un tiempo tan corto (creo que fue un poco más de un año el tiempo que el proyecto estuvo disponible), pero así es el mundo del software libre, ya que se depende del trabajo voluntario de comunidades de desarrolladores que buscan ofrecer piezas de software increíbles sin esperar nada a cambio. "Por amor al arte", como dicen. Solo nos queda agradecer a estas personas por la maravillosa experiencia que nos ofrecieron al traer al mundo a Apricity OS, y también nos deja la motivación para que nosotros nos animemos a integrarnos a alguna de estas apreciables comunidades.

Saludos, y hasta la próxima.
Con la tecnología de Blogger.