Configurar Git (BitBucket) en Visual Studio 2010 y no morir en el intento

escrito por Víctor Fernández Portero 10. marzo 2012 10:47 | Comentarios (1)

 

Que Git se ha convertido en el más famoso y mejor controlador de versiones de código es una cosa que ya sabéis pero, ¿cómo puedo configurar las herramientas necesarias para poder trabajar con un repositorio Git en mi Visual Studio 2010?

El objetivo de este pequeño tutorial es conseguirlo sin morir en el intento Wink

Nota: Este tutorial no explica el funcionamiento de un control de versiones por lo que doy por supuesto que todo el mundo sabe lo que es un commit, push, pull, branch, etc... Otro día haré un artículo dedicado a explicar más a fondo como funciona un control de versiones :)

 

¿BitBucket o GitHub?

¡Para empezar! Necesitamos una cuenta en algún servicio de repositorio de Git (si no dispones de uno local o el de tu empresa).

Actualmente existen dos grandes servicios gratuitos de Git que son GitHub y BitBucket. No voy a entrar a discutir cual es mejor en este artículo, solo diré que BitBucket te permite tener, de forma gratuita, repositorios privados lo cual es perfecto para esas pequeñas aplicaciones que tienes en casa y quieres salvaguardar.

Es por este motivo principalmente por lo que yo uso BitBucket como Source Control :)

 

¿Ya tienes cuenta en BitBucket? ¡Descarguemos Git!

 

Descargando y Configurando Git para Windows

Bien, lo primero que necesitamos es descargar Git para Windows el cual podemos encontrar aquí: http://code.google.com/p/msysgit/downloads/list

Descarga e instala la última versión disponible.

 

No hay que modificar casi nada durante el proceso de instalación. La única opción que recomiendo modificar es la de "Adjusing your PATH environment" la cual aconsejo cambiar de "Use Git Bash only" a "Run git from the Windows Command Prompt" tal y como se ve en la siguiente captura:

 

El resto lo puedes dejar igual.

 

¡Bien! ¡Ya lo tenemos instalado! Ahora tenemos que configurarlo para que funcione con nuestra cuenta de BitBucktet.

Para ello ejecutamos el "Git Bash" (si, es una consola, no te asustes, jeje) e introducimos la configuración global de nuestro usuario de BitBucket e Email escribiendo:

git config --global user.name "tu usuario de BitBucket aquí"

git config --globla user.email "tu email de BitBucket aquí"

 

Con esto ya lo tenemos!

Ahora vamos a configurar las herramientas en el Visual Studio 2010.

Configurando Git en Visual Studio 2010

Debido a que Visual Studio no incluye Git como control de código por defecto (solo incluye SourceSafe y Team Foundation Server) necesitamos instalar una pequeña extensión de Git para que funcione.
Para ello vamos a "Tools > Extension Manager" o "Herramientas > Administrador de Extensiones" en castellano y, en la Galería Online buscamos "Git" para instalar el "Git Source Control Provider":

Una vez instalado lo escogemos como Source Control por defecto en "Herramientas > Opciones > Source Control > Selección de Complemento > Git Source Control Provider"

 

Lo próximo que debemos hacer es abrir (o crear) la solución que queremos subir a BitBucket y, pulsando botón derecho sobre el nombre de la solución clickamos en "New Repository".

Esto creará un nuevo repositorio Git en el mismo directorio en el que está la solución.

Verás que en el "Solution Explorer" aparecen unos símbolos con un "+" amarillo. Esto indica que el fichero es nuevo y no se encuentra en tu repositorio local.

Haciendo click derecho de nuevo sobre la solución y pulsando en "Pending Changes" podremos ver el listado de ficheros pendientes, escribir un comentario y hacer el primer commit contra tu repositorio local.

¡Ya está! ¡Ya tenemos configurado Git para Visual Studio! Eso si, de momento solo lo deja en local y BitBucket ni lo hemos usado.

¿Qué toca ahora? Configurar Git Bash para que suba nuestros commits a BitBucket.

 

Configurar Remote y hacer Push desde Visual Studio a BitBucket

De nuevo botón derecho en la solución > Pending Changes > Git Bash y se nos abrirá la consola de Git. Ahora tenemos que configurar el acceso remoto.

Para ello escribimos lo siguiente:

git remote add origin https://usuario@bitbucket.org/nombre_del_repositorio.git

Supongamos que mi usuario es "vfportero" y mi repositorio en BitBucket se llama "demo". El remote sería así:

git remote add origin https://vfportero@bitbucket.org/demo.git

 

¡Perfecto! Con esto ya podemos escribir: 

git push

Nos pedirá el password de BitBucket y, una vez escrito, y el bash solito se encargará de subir los ficheros al repositorio remoto :)

 

Espero que os haya servido de ayuda.

¡Nos vemos Compilando!

Tags: , , ,

Ingeniería del Software | Source Control

Primeros pasos desarrollando en Windows Phone: Consejos útiles

escrito por Víctor Fernández Portero 26. enero 2012 21:31 | Comentarios (0)

Windows Phone 7 es el nuevo sistema operativo móvil de Microsoft con el que pretende competir con dos grandes ya asentando en el mercado de los operativos para smartphone como iOS y Android.

Windows Phone 7 pretende reinventar el concepto de operativo movil apostando fuerte por un resideño completo de la interfaz (la famosa Metro UI) así como la integración con otros sistemas como XBox Live y Windows 8.

Yo, como buen fan de los productos de Microsoft, no podía perderme esta nueva entrada de los de Redmond al mercado móvil y es por eso que me aventuré a desarrollar una aplicación para el Marketplace en un principio por aprender pero, conforme le he ido dando forma, pensando en, ¿por qué no? ganar algún eurillo :)

 

Más adelante le dedicaré un post a mi primera app de Windows Phone "Echemos cuentas" (que ya está en proceso de aceptación por parte de Microsoft) así que el motivo de este artículo es intentar ayudar a los que, como yo, quieran subirse al barco de Windows Phone Marketplace y no sepan por donde empezar.

¡Aquí van unos cuantos consejitos!

 

¡Empecemos! ¿Qué me tengo que descargar?

Bien, partimos de la base de que eres un desarrollar .NET y que tienes el Visual Studio instalado (y si no ya tardas, jeje) por lo que tenemos que descargar e instalar es el SDK 7.1 de Windows Phone:

Estas herramientas incluyen todo lo necesario para crear un proyecto para Windows Phone así como el emulador para probarlo y depurarlo, herramientas de testeo previo a la publicación al Marketplace y el Expression Blend para poder diseñar los formularios WPF de forma sencilla y eficaz.
 

Bien, ¿por dónde empiezo?

Esto puede parecer un mundo si no damos los pasos correctos y, como no quiero abrumar con mucha información os comentaré los pasos que yo hice hasta poder terminar con éxito mi primera aplicación:

Revisa los "Quick Starts" del App Hub

App Hub es el punto de encuentro de todos los desarrolladores de Windows Phone y XBox Live en el que encontraremos tutoriales, herramientas, recursos y los foros en los que preguntar nuestras dudas.

Un ejemplo de estos tutoriales es el clásico "Hello World" que ilustra lo fácil que es crear un nuevo proyecto en Windows Phone y lanzarlo en nuestro emulador o teléfono: 

Con esto tienes material para probar, aprender y coger soltura con el framework.
 

No inventes la rueda: usa los controles Silverlight de Codeplex

Los controles por defecto del SDK están muy bien ya que te permiten montar una interfaz Metro sin apenas esfuerzo pero si de verdad queremos sacarle jugo a nuestra aplicación y que deslumbre a todo aquel que la use no te compliques y usas los controles Silverlight para Windows Phone de Codeplex:

Controles como el LongListSelector o el ExpanderView harán nuestro trabajo de diseño y funcionalidad muchísimo más fácil. 
Además estos controles son OpenSource y se van actualizando periodicamente así que no pierdas de vista Codeplex!
 

No tengas miedo y pregunta en los foros de desarrolladores

Si algo tiene la comunidad de desarrolladores de Windows Phone de habla hispana es una gran predisposición para ayudar a los demás, resolver sus dudas, dar consejos y crear comunidad.

Todo esto se ve plasmado de forma clara en los más que útiles foros de MSDN para Desarrollo de Windows Phone que modera el gran Josue Yeray (un referente dentro del mundo del desarrollo Windows Phone):

En el foro podrás preguntar cualquier duda que tengas desde aspectos técnicos hasta dudas sobre el modo de publicar una app en el Marketplace.
Echa un vistazo y plantea tus dudas. Verás como en breve un desarrollador como tu te echa una mano :)
 

Y, ¿qué tipo de aplicación hago?

A esta pregunta hay dos posibles respuestas.

Puedes hacer algo que te sea útil / interesante a ti y que no haya nada en el Marketplace que lo haga como tu quieres (esa es la ventaja de poder programar lo que quieras desde el mismo Visual Studio y poder instalarlo directamente en tu movil Windows Phone). En mi caso fue solventar un problema de gestión que tenemos en mi grupo de amigos a la hora de hacer las cuentas en los viajes, cenas, cumpleaños, etc... así que acabé programando una aplicación dedicada en la que yo era mi propio cliente.

 

Por otro lado, si quieres ganar dinero con la aplicación, lo que te recomiendo es buscar un nicho de mercado en el Marketplace y hacer una aplicación que rellene ese hueco. También puedes fijarte en aplicaciones que han tenido éxito en otras plataformas y, no copiar, si no hacer una versión con características similares aprovechando toda la potencia de la interfaz Metro y los Live Tiles de Mango.

Windows Phone 7 es una plataforma joven y aún quedan muchos tipos de aplicaciones por hacer así que busca algo que pueda interesar al público y ¡ponte con ello!

Ah! Y no desesperes si tu aplicación no funciona del todo bien en el mercado. Puedes publicar las aplicaciones que pago que quieras y hasta 100 gratuitas (a partir de 100 se pagan 19.90$ por cada publicación) así que no desesperes y sigue probando.

Quien sabe... a lo mejor estás detrás del nuevo WhatsApp ;-)

 

¿Dónde consigo material más avanzado?

Si ya has hecho los tutoriales, tienes una buena idea y las estás llevando a cabo es posible que te surjan dudas sobre cómo hacer ciertas cosas o sobre como utilizar ciertos controles.

Como he comentado antes los foros son muy útiles pero, para estas situaciones, lo que realmente me ha sacado las castañas del fuego es el libro de Josuey Yeray: "Windows Phone 7.5: Desarrollo de aplicaciones en Silverlight" que podeis comprar aquí: http://www.campusmvp.com/Catalogo/Product-Windows-Phone-7.5-Mango---Desarrollo-Silverlight_142.aspx

El libro explica de forma precisa todos los aspectos que envuelven al desarrollo de aplicaciones para Windows Phone Mango con claros ejemplos (todos adjuntados en forma de proyectos para Visual Studio que podemos compilar y probar directamente en nuestro emulador!).

¡Sin duda una gran compra 100% recomendable!

 

Por otro lado, otro proyecto al que no podemos quitarle el ojo de encima es el recién estrenado PodCast sobre desarrollo en Windows Phone: Windows Phone Controla del omnipresente Josue Yeray y Rafael Serna.

 
Mensualmente nos traerán las noticias más destacadas dentro del mundo del desarrollo en Windows Phone así como explicar una API dentro del framework (por ejemplo, en este primer podcast explican el API del Live Connect!!)

Lo dicho, un proyecto más que interesante que promete ser una fuente de información y conocimiento cómoda, accesible y frecuente y es que, ¿Quien no querría sentarse en un bar a tomar una cerveza con dos grandes de Windows Phone como son Yeray y Serna?

 

¡A programar!

Con esto termino mi pequeña ruta de viaje dentro del mundo de Windows Phone. Espero que estos consejos os sean útiles a la hora de empezar con vuestra primera aplicación para el Marketplace y recordad que, si tenéis cualquier duda estamos en los foros de la MSDN para resolverla.

 

Un saludo y nos vemos compilando!!

Tags: , , ,

Windows Phone 7

TDD: Un ejemplo práctico sobre como mejorar la calidad de tu código

escrito por Víctor Fernández Portero 13. noviembre 2011 19:10 | Comentarios (0)

 

Ultimamente se habla mucho de diseño ágil pero la realidad de muchas empresas de desarrollo dista mucho de implementarlo de forma eficiente o directamente de usarlo en cualquiera de sus aspectos

Y es que el agilismo es una metodología muy fácil de entender pero costosa de poner en práctica si no se hace de la manera adecuada.

Por ese mismo motivo he visto que sería interesante dedicar una entrada a explicar de forma práctica y sencilla qué es TDD y cómo se utiliza en un proyecto.

 

Lo primero de todo confesar que no soy un experto en la materia y por ello es de obligada necesidad indicar que, si quereis profundizar más en estos temas, vayais a la web "www.dirigidoportests.com" de Carlos Blé, autor de "Diseño Ágil con TDD" el libro de cabecera de todo aquel desarrollador que quiera empezar a trabajar con esta metodología.

Además dar las gracias encarecidamente a Javier Casal por darme las clases magistrales de TDD y la gente de 12Meses12Katas por el ejemplo práctico para compartir con todos vosotros :)

 

¿Qué es TDD (Test Driven Development)?

El diseño dirigido por test, o TDD, es una técnica de diseño e implementación de software consistente en generar las pruebas unitarias justas y necesarias para obtener la implementación de las funciones que el cliente necesita minimizando los errores que llegan a producción.

El diseño por test no solo nos ahorra implementar más de lo debido si no que nos informa de si un cambio posterior "rompe" algo de lo que ya hemos implementado y nos facilita la tarea de entregar un código más limpio y libre de errores.

TDD no se trata de escribir cientos y cientos de pruebas si no se escribir las que necesites (y cuanto más simples mejor) para cumplir las necesidades del cliente y poder, posteriormente, empezar a desarrollar para cumplir dichos requisitos.

 

Como indico en el título esto es un ejemplo práctico sobre como utilizar TDD para resolver un problema concreto por lo que he hecho uso del problema de Noviembre del 2011 de 12Meses12Katas para ilustrar este post: KataPotter

Para ello vamos a crear una biblioteca de clases C# en Visual Studio 2010 y usaremos el framework de pruebas NUnit.

 

Explicando el problema

Bien, el problema que se nos plantea es la creación de un programa que calcule el importe de una coleción de libros aplicando un determinado descuento en función de los distintos tipos de libros que compremos. Partiendo de que cada libro tiene un coste de 8€ el cliente nos indica que, si se adquieren dos libros distintos, se aplique un 5% de descuento a ambos libros, un 10% si se compran 3, un 20% para 4 distintos y un 25% para la serie completa de 5 libros.

Otra condición del cliente es que el programa obtenga el precio más económico si hay varias combinaciones posibles de packs.

 

Como entrada recibiremos un array con los códigos de los libros a comprar (de 0 a 4) y como salida obtendremos un valor double.

¡Muy bien! Ya sabemos que tenemos que hacer y que quiere el cliente por lo que vamos a escribir las primeras pruebas.

 

Pruebas Sencillas

Lo primero que debemos hacer es escribir unas pruebas sencillas que implementen los casos más básicos. La primera y más sencilla es que cuando nuestra cesta de compra esté vacia el precio total es 0. En NUnit sería así:

[Test]
public void EmptyBasket()
{
     Assert.AreEqual(0, _bookPriceCalculator.CalculateBasket(new int[] { }));
}

Sin entrar en explicar la sintaxis de NUnit simplemente indicar que esta prueba comprueba que si se le pasa un array vacio el sistema devuelve 0.

¿Cómo resolvemos esta prueba con la menor cantidad de código posible? Muy fácil:

public double CalculateBasket(int[] books)
{
     return 0;
}

¡Exacto! Esa es la solución más sencilla que hace que la prueba sea correcta. Obviamente en cuanto añadamos una segunda prueba tendremos que rehacer nuestro código pero de esto se trata TDD.

¡Ok! Vamos ha añadir una nueva prueba para indicar una nueva condición impuesta por el cliente: Cada libro vale 8€

[Test]
public void TwoSameBook()
{
     Assert.AreEqual(8 * 2, _bookPriceCalculator.CalculateBasket(new int[] { 0, 0 }));
}

En esta prueba indicamos que si se compran dos veces el libro "0" el precio total es de 16€. ¿Cómo modificamos nuestro método para que pase las dos pruebas?

public double CalculateBasket(int[] books)
{
     return books.Length * 8;
}

¡Vale! No es muy elegante pero solucionaría cualquier prueba que no implique un descuento por lo que podemos cerrar el capítulo de pruebas sencillas.

 

Añadiendo Funcionalidad: Calculando Descuentos

Nuestro cliente nos había puesto como premisa que, si se compraban dos o más libros distintos había que aplicar un descuento determinado por lo que vamos a crear una serie de pruebas de ejemplo que implementen esta funcionalidad:

[Test]
public void TwoDifferentBooks()
{
            Assert.AreEqual(8 * 2 * 0.95, _bookPriceCalculator.CalculateBasket(new int[] { 0, 1 }));
}

[Test]
public void SeveralDiscountsTwo_One()
{
            Assert.AreEqual(8 + (8 * 2 * 0.95), _bookPriceCalculator.CalculateBasket(new int[] { 0, 0, 1 }));
}

Como veis en las pruebas tan solo declaramos una entrada de datos y la solución que nuestro cliente espera. Es trabajo del desarrollador el encontrar el modo en que el código del programa satisfaga todas las nuevas pruebas sin "romper" ninguna de las anteriores ya implementadas.

La solución que se me ha ocurrido a mi es hacer una clase "BookPack" que simbolice un "paquete de libros" donde todos los libros deben de ser distintos por lo que cada compra se traduce realmente en varios "BookPacks" cada uno con su precio y descuento.

Sin tener en cuenta la última condición (que indicaba que se ha de escoger la combinación más económica), la solución más sencilla es esta:

List<BookPack> BookPacks = new List<BookPack>();

foreach (int bookCode in books)
{
     BookPack currentBookPack = null;
     
     foreach (var bookPack in BookPacks)
     {
          if (!bookPack.HasThisBook(bookCode))
          {
              currentBookPack = bookPack;          
          }
     }

     if (currentBookPack == null)
            {
                BookPacks.Add(new BookPack(bookCode));
            }
            else
            {
                currentBookPack .Books.Add(bookCode);
            }
}
return BookPacks.Sum(bookPack => BookPack.GetBookPackPrice(bookPack.Books.Count));

Donde "GetBookPackPrice" devuelve el precio del paquete en función de cuantos libros tiene:

public static double GetBookPackPrice(int quantity)
        {
            return 8 * quantity * GetDiscountPerDifferentBooks(quantity);
        }
//GetDiscountPerDifferentBooks devuelve 1, 0.95, 0.9, 0.8 o 0.75 en función de si se compran 1, 2, 3, 4 o 5 libros distintos respectivamente.

Con esto ya tenemos implementada tanto la funcionalidad básica (ningún libro o varios libros iguales) como el descuento básico por "paquetes de libros". Sólo nos faltaría añadir la última condición del cliente: que se elija la combinación más económica a la hora de hacer los paquetes.

 

Pruebas Finales: Obteniendo el paquete más económico

No es lo mismo hacer dos paquetes de 4 libros (51.2€ en total) que 1 de 5 y otro de 3 (51.6€). Con el código anterior obtendríamos la opción más desfavorable ya que solo se crea un nuevo paquete cuando el libro actual ya se encuentra en el paquete actual y no se tiene en cuenta el importe final.

Para añadir esta nueva funcionalidad vamos a escribir la última prueba:

[Test]
        public void SeveralDiscountsFourFour()
        {
            Assert.AreEqual(2 * (8 * 4 * 0.8), _bookPriceCalculator.CalculateBasket(new int[] { 0, 0, 1, 1, 2, 2, 3, 4 }));
        }

La implementación para este caso consiste en cambiar el concepto "CurrentBookPack" que tan solo va rellenando paquetes por "CheapestBookPack" el cual compara entre los distintos paquetes y se queda con el más económico.

Como el código resultante ya es más largo y enrevesado como para ponerlo en un post mejor lo veis directamente en mi repositorio de GitHub para este ejemplo ;-):

https://github.com/vfportero/Noviembre-KataPotter/tree/master/vfportero

 

Conclusiones Finales

Creo que este es un gran ejemplo para explicar las virtudes de TDD ya que en un mismo proyecto hemos tenido que hacer 3 modificaciones que han alterado por completo el funcionamiento de la aplicación

Al principio solo teníamos que calcular importes sencillos (8 * unidades), después se añadió unos descuentos por volumen para terminar con un sistema más inteligente que se queda con la combinación más económica.

Ahora extrapola este ejemplo a un proyecto real con cientos de clases y miles de líneas y piensa que pasaría si tuvieras que hacer este tipo de cambios... asusta, ¿verdad?

Y es que ¿cuantas veces hemos "arreglado algo y roto otro cosa"? ¿cuantas veces los requerimientos del software cambian y debemos adaptarnos rapidamente a las nuevas necesidades? ¿cuantas veces programamos más de lo debido?

 

TDD ayuda a solucionar estos problemas facilitandote el modo en el que organizas tus tareas. Cuando programas primero una prueba estás abstrayendote de algoritmos y estrategias para centrarte en entender el problema y la solución exacta que quiere el cliente.

Si logras crear pruebas simples que explican una pequeña parte del código podrás tener un sistema casi perfecto cuando el producto se entregue además de ganar en flexibilidad en caso de los requerimientos cambien en medio del desarrollo.

 

Está claro que escribir pruebas antes de programar es un trabajo extra que en muchos casos no se puede asumir pero, a la larga, ahorra mucho tiempo en mantenimiento y evita problemas de código heredado.

 

TDD, como otras herramientas dentro del agilismo, solo te da una serie de "buenas practicas" que te ayudan a mejorar tu calidad como desarrollador. Está en tu mano decidir hasta que punto utilizar TDD :-)

 

Para terminar solo invitar a todos aquellos interesados en este tema a que se pasen por la web de 12Meses12Katas donde encontraran ejemplos y soluciones a problemas como este "KataPotter" que hemos explicado aquí. Os recomiendo que os junteis con ese amigo programador con el que siempre haceis el friki, compreis una caja de cervezas, y empeceis a trabajar con una de estas Katas en parejas.

Mientras uno programa una prueba el otro programa el código que la implementa y viceversa. Vereis como TDD se ve de otra manera ;-)

 

¡Nos vemos Compilando!

Tags: , , , , ,

Ingeniería del Software | TDD

Configurar Réplica Maestro - Esclavo en MySql Server

escrito por Víctor Fernández Portero 7. octubre 2011 12:47 | Comentarios (5)

 

Sé que este artículo se aleja un poco de lo que suelo escribir por aquí pero la clase magistral que me ha dado mi gran amigo Pedro Sanz sobre MySql bien se merece una entrada en el blog :-)

 

Hoy hemos tenido que montar para un cliente un servidor de réplica de MySql en el que era imperioso que los datos se espejeran de forma inmediata entre el servidor maestro y el esclavo.

Una réplica de MySql Server hace uso del fichero binario de transacciones para almacenar en el maestro todos los cambios reaizados (UPDATES, DELETES, CREATE, etc..) para que un servidor externo lo lea y replique exactamente los mismos cambios en su propia base de datos.

De este modo tenemos uno o más servidores MySql esclavos haciendo las mismas transacciones que el maestro para así tener los mismos datos en diferentes servidores cosa que se realmente útil y, no sólo ante caídas, ya que es posible configurar nuestra aplicación para compartir las SELECT entre distintos nodos de MySql y mejorar así el rendimiento.

 

Bueno, menos teoría y vamos al lío!.

Lo primero que debemos hacer es configurar el servidor maestro para que almacene el log binario y asignarle un identificador. Para ello editamos el my.cnf añadiendo (o editando si ya las tiene) las siguientes entradas:

#Identificador único del servidor maestro
server-id=1
#Nombre del fichero binario donde se almacenarán las transacciones
log-bin=mysql-bin
sync_binlog=1
#Tamaño del fichero de log tras lo que se truncara
max-binlog-size=500M
expire_logs_days=4
innodb_flush_log_at_trx_commit=1

Como siempre que modificamos un my.cnf hay que reiniciar el servicio de MySql para que acepte los cambios.

Luego tenemos que hacer lo propio con el (o los) esclavo(s). Modificar el my.cnf con los siguientes parámetros y luego reiniciar el servicio:

#Indentificador único del esclavo
server-id=2
relay-log=mysqld-relay-bin
max-relay-log-size=500M
relay_log_purge=1

¡Muy bien! Ya tenemos un servidor maestro y un esclavo pero ahora necesitamos crear un usuario para que el esclavo se conecte al maestro y pueda leer el log de transacciones. Para ello vamos a crear un nuevo usuario llamado "replicador" (el nombre y pass puede variar, jeje) en el master con privilegios de "REPLICATION SLAVE":

CREATE USER replicador IDENTIFIED BY 'elpassword';

Y luego le damos los permisos de REPLICATION SLAVE:

GRANT REPLICATION SLAVE ON *.* TO 'replicador'@'%' IDENTIFIED BY 'elpassword';
FLUSH PRIVILEGES;

Ok! Ya tenemos los servidores bien configurados y el usuario que usaremos como replicador por lo que lo próximo que tenemos que hacer es crear una copia inicial o "snapshot" de la base de datos que queremos replicar para luego poder indicar al servidor esclavo desde dónde tiene que empezar a leer.

Para hacer el snapshot primero ejecutamos las siguientes consultas:

FLUSH TABLES;
FLUSH TABLES WITH READ LOCK;
SHOW MASTER STATUS;

Ten en cuenta que al hacer "READ LOCK" estamos bloqueando la tabla para que nadie cambie nada por lo que lo que viene a continuación deberíamos hacerlo lo más rápidamente posible.

El SHOW MASTER STATUS muestra dos valores que debemos anotar que son el "File" y "Position". Necesitaremos indicarselos al servidor de réplica una vez hayamos cargado la copia inicial.

+------------------+----------+--------------+------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000001 |     492 |              |                  |
+------------------+----------+--------------+------------------+
1 row in set (0.00 sec)

¡Muy bien! Vamos al servidor esclavo y lo terminamos de configurar.

Lo primero es cargar una copia de seguridad de base de datos que queremos replicar del master al esclavo (puedes usar el método que quieras, mysqldump, HeidSql, MySql Workbench...) y, una vez restaurada, configurar el esclavo e iniciarlo.

En este ejemplo vamos a suponer que el servidor maestro está alojado en 10.0.1.10. Fíjate que tenemos que indicar el File y la Position que hemos obtenido antes del SHOW MASTER STATUS:

CHANGE MASTER TO MASTER_HOST='10.0.1.10', MASTER_USER='replicador', MASTER_PASSWORD='elpassword', MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=492, MASTER_PORT=3306;

START SLAVE;

Para terminar volvemos al maestro y desbloqueamos de nuevo las tablas para que puedan volver a editar datos:

UNLOCK TABLES;

¡Ya está! Si no ha pasado nada raro tendremos el servidor esclavo con la carga inicial funcionando y todo cambio en el master se replicara por arte de magia.

Si queremos saber el estado del servidor de réplica podemos usar la consulta:

SHOW SLAVE STATUS\G

Que nos mostrará un listado de datos. Yo miro el valor "Seconds_Behind_Master" que indica que "retraso" tiene el servidor esclavo respecto al maestro (si es NULL es que no va. Revisa el "Slave_IO_State" y "Last_Error").

Ahora empieza a meter datos en la base de datos maestra y verás como ellos solitos aparecen en la esclava... ¡brujería! :-)

 

Espero que esto os sea útil.

Nos vemos Compilando!!

Tags: , , , ,

MySql

Trasteando con Windows 8, Visual Studio 11 y .NET 4.5: Mi primera aplicación Metro

escrito por Víctor Fernández Portero 21. septiembre 2011 15:18 | Comentarios (2)

 

La pasada semana sufrimos un aluvión de noticias relacionadas con la presentación de la nueva criatura de Microsoft: Windows 8.

Windows 8

Con una renovada Interfaz llamada "Metro", Windows 8 promete revolucionar el mercado de los operativos ofrenciendo un sistema multiplataforma capaz de ser ejecutado desde el sobremesa más potente hasta la tablet más económica.

 

Pero este post no va sobre que es Metro, Windows 8 o que trae de nuevo el Internet Explorer 10; vamos a hablar de lo que realmente nos interesa:

  • ¿Qué trae el nuevo Visual Studio 11 y su .NET 4.5?
  • ¿Cómo se desarrolla con Metro?
  • ¿Qué son y cómo funcionan los nuevo métodos asíncronos?
 

Visual Studio 11: Creando un proyecto Metro

En la beta del VS 11 nos vienen por defecto varios tipos de plantillas de aplicaciones: Metro, Grid y Split. En este caso vamos a usar la plantilla por defecto "Metro" para hacer una aplicación Metro de ejemplo con el listado en tiempo real de post de este blog y su contenido como detalle.

 

Lo primero que nos llama la atención es que la interfaz está completamente en WPF (Windows Presentation Foundation) así que solo tenemos una página .xaml y su correspondiente .cs. 

Ok, no nos asustemos, es algo distinto a lo que estamos acostumbrados pero no pasa nada. El objetivo de este ejemplo es conseguir una aplicación que liste el contenido del feed de esta web en un ListView y que cuando pulsemos en un post cargue el html de dicho post en el cuerpo de la aplicación.

Vamos a empezar primero por crear la clase FeedData que almacenará los datos leídos para luego obtener de forma asíncrona el valor del feed directamente de la url: http://www.compilando.es/syndication.axd

 

C# 5 y Windows.Web.Syndication: Obtener datos del Feed Rss

Bien, vamos a bindear una lista de "items" rss que tendrán las propiedades de Título, Fecha, Autor y Contenido. Lo primero es crearnos la clase que usaremos para bindear con el futuro control y nos creamos también una coleccion de tipo "ObservableCollection" para que el xaml pueda bindearlo correctamente.

El código como veis es muy simple:

public class FeedData
    {
        public string Titulo { get; set; }

        private ObservableCollection<FeedItem> _Items = new ObservableCollection<FeedItem>();
        public ObservableCollection<FeedItem> Items
        {
            get
            {
                return this._Items;
            }
        }
    }

    public class FeedItem
    {
        public string Titulo { get; set; }
        public string Autor { get; set; }
        public string Contenido { get; set; }
        public DateTime Fecha { get; set; }

    }

 

Una vez creada la clase vamos al meollo del asunto que es como leed del feed, bajarse los datos y crear los correspondientes "FeedItems". Actualmente tenemos que usar XmlReaders y métodos más o menos manuales para leer un feed rss.

Con .NET 4.5 tenemos una multitud de clases nuevas que nos ofrecen funcionalidades no existentes hasta ahora como Windows.Web.Syndication que nos da una serie de clase y métodos para tratar con feed's rss así como la posibilidad de ejecutarlo de forma asíncrona.

¡Al grano! Necesitamos un método que se ejecute al iniciar la aplicación, que lea del feed y bindee el resultado en el "DataContext" de la página. Como queremos que la aplicación no se quede "frita" mientras baja el feed vamos a hacer uso de los métodos asíncronos para invocar el método.

Como vale más código que mil palabras os lo pego y lo voy comentado inline ;-)

// Hay que firmar el método como "async" y "Task" para que el compilador cree un hilo para el solo y podamos hacer uso de las herramientas asíncronas
        private async Task ObtenerFeedAsincronamente(string feedUrl)
        {
            // using Windows.Web.Syndication;
            // SyndicationClient -> Clase para trabajar con Feed's RSS
            SyndicationClient client = new SyndicationClient();
            Uri feedUri = new Uri(feedUrl);

           
                //Obtenemos el feed de la URL dada y esperamos a que termine añadiendo la palabra clave "await" 
                SyndicationFeed feed = await client.RetrieveFeedAsync(feedUri);

                // Ya tenemos en "feed" todos los datos necesarios. Sólo tenemos que recorrerlo y crear las clases para el bindeo
                FeedData feedData = new FeedData();
                feedData.Titulo = feed.Title.Text;

                foreach (SyndicationItem item in feed.Items)
                {
                    FeedItem feedItem = new FeedItem();
                    feedItem.Titulo = item.Title.Text;
                    feedItem.Fecha = item.PublishedDate.DateTime;
                    feedItem.Autor = item.Authors[0].Name;
                    if (feed.SourceFormat == SyndicationFormat.Atom10)
                    {
                        feedItem.Contenido = item.Content.Text;
                    }
                    else if (feed.SourceFormat == SyndicationFormat.Rss20)
                    {
                        feedItem.Contenido = item.Summary.Text;
                    }
                    feedData.Items.Add(feedItem);
                }
                // Bindeamos el ObservableCollection<FeedItem> y seleccionamos el primero
                this.DataContext = feedData;
                ItemListView.SelectedIndex = 0;
            
        }

 

¡Así de fácil! Basta con poner "async" como firma del método y "await" en el momento que queremos que se pare la ejecución de este método para que el compilador salte fuera del método, siga su ejecución y escuchando eventos y, cuando termine la llamada "await" vuelva a la siguiente linea y siga ejecutandose. Con esto conseguimos que el usuario pueda seguir trabajando con la aplicación mientras la aplicación trabaja por debajo.

Bien, ya hemos obtenido los datos pero, ¿cómo los muestro en mi interfaz?

¡Vamos a por el WPF!

 

Controles WPF: Bindeo de Datos en Metro UI

En nuestro MainPage.xaml por defecto veremos un "Grid" ya creado que es la rejilla en la que vamos a crear los controles. Como queremos hacer una aplicación Metro bien chula como las que se ven en los videos de presentación de Windows 8 vamos a montar una interfaz con una cabecera, una lista de artículos en un lateral usando 2/5 de la pantalla y su contenido en el centro ocupando los 3/5 restantes.

Bien, con estas premisas necesitamos hacer uso de dos controles: ListView y WebView.

Un ListView es muy muy parecido a lo que hemos visto toda la vida: un control que repite ciertos elementos una vez por cada item

WebView es un control que interpreta HTML como si de un navegador se tratará lo cual nos viene de perlas para mostrar el contenido del post que previamente hemos leído.

Como antes os comento entre líneas. Ojo a cómo se bindea el Grid que contiene el cuerpo del post que parece magia :)

 

<Grid x:Name="LayoutRoot" Background="#FF0C0C0C">
        <!-- Definimos 2 lineas. Una de 140px para el título y la siguiente que llegue hasta el final-->
        <Grid.RowDefinitions>
            <RowDefinition Height="140" />
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>

        <!-- Titulo. Corresponde con la primera "row" de 140px -->
        <TextBlock x:Name="TitleText" Text="Compilando.ES RSS FEED"
                   VerticalAlignment="Center" FontSize="48" Margin="56,0,0,0"/>

        <!-- Cuerpo. Como veis indicamos que es la row "1" por lo que debe usar el resto de la pantalla -->
        <Grid Grid.Row="1">
            <!--Definimos dentro del Grid principal otro Grid secundario dividido en 5 partes con dos columnas.-->
            <!--La primera tendrá un ancho mínimo de 320px y usará 2/5 partes del espacio total-->
            <!--La segunda usará 3/5 parte del ancho total del Grid-->
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="2*" MinWidth="320" />
                <ColumnDefinition Width="3*" />
            </Grid.ColumnDefinitions>

            <!-- Listado de Post -->
            <!-- Indicamos que utilice el ObservableCollection<FeedItem> llamado Items del DataContext de la página -->
            <ListView x:Name="ItemListView"  
                      ItemsSource="{Binding Path=Items}"
                      SelectionChanged="ItemListView_SelectionChanged"
                      Margin="60,0,0,10">
                <ListView.ItemTemplate>
                    <DataTemplate>
                        <!-- Controles que se repetirán una vez por cada Item en "Items" -->
                        <!-- Usamos un StackPanel con 3 TextBlock bindeados -->
                        <StackPanel>
                            <TextBlock Text="{Binding Path=Titulo}"  
                                       FontSize="24" Margin="5,0,0,0" TextWrapping="Wrap" />
                            <TextBlock Text="{Binding Path=Autor}" 
                                       FontSize="16" Margin="15,0,0,0"/>
                            <TextBlock Text="{Binding Path=Fecha}" 
                                       FontSize="16" Margin="15,0,0,0"/>
                        </StackPanel>
                    </DataTemplate>
                </ListView.ItemTemplate>
            </ListView>

            <!-- Cuerpo del Post -->
            <!-- Se bindea en función del elemento seleccionado del ItemListView -->
            <Grid DataContext="{Binding ElementName=ItemListView, Path=SelectedItem}"
                  Grid.Column="1" Margin="25,0,0,0">
                <!-- Como antes le decimos que tiene 2 filas. La primera será un TextBlock con el título del Post y la segunda el control WebView que mostrará el contenido del post -->
                <Grid.RowDefinitions>
                    <RowDefinition Height="Auto" />
                    <RowDefinition Height="*" />
                </Grid.RowDefinitions>
                <TextBlock Text="{Binding Path=Titulo}" FontSize="24"/>
                <WebView x:Name="ContentView" Grid.Row="1" Margin="0,5,20,20"/>
            </Grid>
        </Grid>
    </Grid>

 

¡Casi casi lo tenemos! Como veis en los comentarios el Grid "Cuerpo" se bindea en función del elemento seleccionado del ItemListView (lo que nos ahorra bastante código) pero ¿cómo cargamos el contenido HTML dentro del WebView?

Bueno, nos toca usar el evento "ItemListView_SelectionChanged" del ListView para ello:

private void ItemListView_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            FeedItem feedItem = (sender as ListView).SelectedItem as FeedItem;
            if (feedItem != null)
            {
                // Si tiene contenido simplemente se lo "encasquetamos" al WebView y el solito interpreta el HTML como si fuera un navegador.
                ContentView.NavigateToString(feedItem.Contenido);
            }
        }

 

¡Ya está! Tenemos nuestra primera aplicación Metro que encima es útil y hasta bonita!!

 

Conclusiones

Las nuevas mejoras de C# 5 sobre sincronía son fantásticas ya que nos permite mover el flujo de la aplicación como queramos de forma muy sencilla aunque quizá haya que aprender bien a como y cuando usarlas y sobre la interfaz Metro que decir... yo estoy  enamorado. Decían que Microsoft tenía mal gusto... Quien rie el último... jeje ;-)

 

No voy a entrar en polémicas sobre si se llevará un batacazo o no, sobre si la gente sabrá usar la nueva interfaz o si se perderá en el intento, si Windows se ha reinventado a si mismo... sólo sé que este movimiento de Microsoft facilitando las herramientas de desarrollo con tanto tiempo de antelación de manera gratuita para que todos las probemos no es una casualidad. Cuando tengamos Windows 8 entre nuestras manos ya habrán cientos de apps listas para ser usadas e incluidas en al Windows Store que funcionarán tanto en Windows 8 como en Windows Phone y yo, por mi parte, no pienso perder la oportunidad de seguir trabajando con esta tecnología :-)

 

Por si alguien tiene la beta y quiere trastear con mi código os dejo el ZIP con la solución completa!

Compilando_ES_Metro_Example.zip (111,39 kb)

 

¡Nos vemos Compilando!

Tags: , , , ,

.NET 4.5 | Windows 8 | WPF

Acerca de...

Mi nombre es Víctor Fernández Portero y soy un amante de la ingeniería del software a la que llevo dedicandome desde el 2002.

Actualmente trabajo como desarrollador web en entornos .NET Avanzis donde tengo la oporturnidad de trabajar con grandes profesionales del sector así como de emplear las últimas metodologías y tecnologías .NET

LinkedIn Twitter @vfportero

Mi Windows Phone

¡Descarga mis aplicaciones desde el Marketplace para tu Windows Phone!

Echemos Cuentas

Microsoft Tag Echemos Cuentas App

Hosting Recomendado

Durante más de 5 años he trabajado como desarrollador y miembro del soporte técnico de Domitienda por lo que recomiendo encarecidamente sus servicios ya que, no solo ofrecen hosting .NET 4.0 a un precio muy reducido si no que su servicio técnico es excelente y el más rápido del mercado (apenas unas horas en el peor de los casos. Incluido el fin de semana).

Todoexpertos.com

Comentarios Recientes

Comment RSS