viernes, 5 de agosto de 2016

Mi método para nombrar variables

Esta es una guía creada en base a mi experiencia, con el fin de saber identificar una variable, cualquiera sea el lenguaje de programación usado, acá uso C#.
Éste es el método que uso para nombrar distintos tipos de variables, aunque con los IDEs modernos, no es tan necesario, pero igual,  puede ayudar.
Dejo lugar para que comente el que quiera, aunque me importe una mierda lo que opinen.

Tips
Los nombres de variables, lo mismo que las clases, las hago en singular y en inglés.
ejemplo:
int icode_person; string sname;
Indico con una letra de que tipo de variable se trata.


Ahora algunos ejemplos de variables comunes:
Int32 o int antepongo la i
ejemplo: int icode;

Int64 o long antepongo la I
ejemplo: Int64 Icode;

string, antepongo s;
ejemplo: string scadena;

float, antepongo f;
ejemplo float fcode;

double, antepongo la D (La d minúscula la dejo para los tipos decimal)
ejemplo: double Dcode;

decimal, antepongo la d
ejemplo: decimal dcode;

bool, antepongo b;
ejemplo: bool bcode;

char, antepongo la c
ejemplo: char ca;

byte, antepongo by (Uso la b para bool)
ejemplo: byte bycode;

Estructuras
Los nombres de las estructuras (struct) van con la palabra Struct en mayúscula la primera y el resto de palabras que componen el nombre, van con la primera en mayúscula.
ejemplo: struct StructPerson{}

Listas y vectores
En el caso de las listas, la letra o letras que van delante, van en minúscula, pero la palabra List y demás palabras que vayan pegadas, comienzan en mayúsculas;
Por ejemplo para nombrar un List de enteros, antepongo la i.
ejemplo: List<int>iList;
Le puedo dar un sentido, por ejemplo, si es una lista de enteros y esos enteros son códigos, pongo así:
List<int>iListCode;
Si es un List de estructuras, por ejemplo la estructura siguiente
struct StructData
{
public int a;
public int b;
}
El List de Estructuras sería:
List<StructData>stListData;
Osea, antepongo st antes del list. Una estructura puede tener múltiples variables, es difícil describir todas, pero al menos aviso que se trata de un List de estructuras.

En los vectores uso una anotación similar, lo mismo hacía con la clase vector de las STL de C++, aquí lo más parecido a vector de C++ es el List, aunque se comporta más como un "deque" de las STL de C++ (no hacer chiste malo, como "deque" carajos me hablan)

Las Clases (class)
Para las clases en un principio anteponía la palabra Class, luego viendo como nombraba Gerardo Sas, uno de mis profesores, simplemente anteponía la letra C, seguido con nombres pegados en mayúsculas en el inicio de cada palabra. por ejemplo: CNumeroPrimo. Finalmente pasé a poner las iniciales de mi empresa, supongamos que trabajo para Microsoft, entonces la clase Microsoft que administra a una persona sería: class MSPerson.

Otras reglas
Acostumbro a no usar acentos ni caracteres especiales en el nombre de las variables y clases, efecto que ya traigo de C++ en donde no se podía (No sé en sus versiones más recientes). Igualmente con C# hago excepciones.

Los Formularios
Como veníamos haciendo en las variables, aquí también se hace en inglés, se usa la primer letra de cada palabra en mayúsculas como se indica a continuación:

Los Formularios Windows Forms
A las ventanas de Windows Forms se les Antepone la palabra Window, por ejemplo una ventana que contiene un listado:
WindowList; Ya saben que el mismo deriva de una clase Form, etc... no voy a andar explicando todo.

Windows Presentation Foundation
Se les Antepone la palabra WPF a la clase que conforma dicha ventana
WPFList

ASP.Net WebForm
Se le antepone la palabra WebForm al formulario web;
Ejemplo: WebFormHome, WebFormProfile

Los diferentes controles preestablecidos que vienen con ASP, Windows Forms, WPF y demás, los nombro en Mayúsculas la primera y anteponiendo el nombre del control, seguido de una descripción de qué hace el control o qué nombre muestra;
Por ejemplo un Label de Windows Forms que muestra el nombre de una persona, ese Label se llamaría LabelFirstName, en el caso del apellido LabelLastName, el TextBox que contiene el nombre y el otro que contiene el apellido serían, TextBoxFirstName y TextBoxLastName.
Supongamos que el nombre y el apellido también son Labels, entonces le agrego la palabra Insert
LabelFirstNameInsert y LabelLastNameInsert, esto es así porque LabelFirstName va a decir "Nombre:" y LabelFirstNameInsert va a decir "German" (Así, sin acento).

Los nombres de los Controles Personales o de Usuarios de WPF y Windows Forms los nombro anteponiendo la palabra Control, lo mismo podría hacer con ASP.Net, pero me quedó el legado de una empresa para la que trabajé que le anteponíamos WebUserControl y no solamente Control
Ejemplos Nombres para controles que contienen un listado de Empleados de una empresa
ASP.Net: WebUserControlListHumanResource
Windows Forms: ControlListHumanResource
WPF: ControlListHumanResource

Las bases de Datos
En la facultad me enseñaron que los nombres de tablas van en singular y las columnas en plural.
El sentido común indica lo contrario, así que en los trabajos que hice, se pasan por los genitales la enseñanza en la facultad, osea es mejor al revés, nombre de tablas en plural y columnas en singular.
Supongamos una tabla "persons", cuya columna de códigos es code, lo que se hace para que esa columna sea única en toda la base de datos, se le agrega un guión bajo y el nombre de la tabla en singular, en este caso sería code_person.


Iré actualizando para indicar cómo se escribe en una Actividad Android o en IOS, ya sea usando XamarinForms o Java.
Gracias por leer.
Bye!!!

viernes, 18 de marzo de 2016

Simple Clock Control AJAX ASP

 Un problema común  en las páginas web es el asunto del hecho de dar la hora. Se puede hacer con javascript, pero daría la hora del lado Cliente, en algunos casos es probable que la computadora esté fuera de hora, generalmente porque son unos bagres y no le cambian la pila.
Supongamos que en nuestra aplicación empresarial (si es empresarial está demás decir que tiene que ser en ASP.Net) a veces necesito dar a conocer al usuario, qué hora tiene el Servidor.
 Esto se puede resolver directamente con ASP.Net sin hacer muchos malabares y simplemente usando Ajax y un UpdatePanel.
 Quiero suponer que cualquier persona que lleve 3 o 4 meses de experiencia en ASP.Net, ya tiene la librería Ajax Toolkit, que la puede descargar desde cualquier lado, incluso desde el mismo Visual Studio.
 Acá vamos a usar Visual Studio, el proyecto será un WebForm (No voy a usar MVC).

El WebForm tiene lo siguiente:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm1.aspx.cs" Inherits="ServerClock.WebForm1" %>

<%@ Register src="ServerClockControl.ascx" tagname="ServerClockControl" tagprefix="uc1" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
 
        <uc1:ServerClockControl ID="ServerClockControl1" runat="server" />
 
    </div>
    </form>
</body>
</html>


Como verán, llamo al Control ServerClockControl que es el que tiene el reloj:
Ahora veamos que tiene adentro el ServerClockControl:


<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="ServerClockControl.ascx.cs" Inherits="ServerClock.ServerClockControl" %>

<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
        <ContentTemplate>
            <asp:Timer ID="TimerFecha" runat="server" Interval="2000" 
                ontick="TimerFecha_Tick">
            </asp:Timer>
            <asp:Timer ID="TimerHora" runat="server" Interval="1000" 
                ontick="TimerHora_Tick">
            </asp:Timer>
            <style type="text/css">
.txtAlign { TEXT-ALIGN: center }
</style>
            <p align="center" style="margin:1% 0;">
            
                <asp:Label ID="Label2" runat="server" Text="Date:"></asp:Label>
            
                </p>
            <p align="center" style="margin:-1% 0;" style="height: 20px">
                &nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;<asp:Label CssClass="txtAlign" ID="LabelFecha" runat="server" Text="12/12/2012 " 
                    BorderColor="#FF3300" BorderStyle="Outset" BorderWidth="1px"></asp:Label>
                &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
                </p>
                
                <p style="margin:1% 0;" align="center">
                <asp:Label ID="Label1" runat="server" Text="Time:"></asp:Label>
                </p>
                <p align="center" style="margin:-1% 0;" style="height: 20px">
                    
                <asp:Label CssClass="txtAlign" ID="LabelHora" runat="server" Text="--:--:--" 
                    style="height: 32px; " 
                    Font-Size="Larger" Font-Bold="True" BackColor="White" BorderColor="#FF3300" 
                        BorderWidth="2px" Height="35px" Width="92px"></asp:Label>
           
            </p>
            
            <br>
            <br>
            <br>
            <br>
        </ContentTemplate>
    </asp:UpdatePanel>


El ServerClockControl posee un UpdatePanel, la magia del UpdatePanel está en que todo lo que esté adentro, puede actualizarse con el Servidor sin necesidad de refrescar la página, el que  lo hace es AJAX, pero el UpdatePanel, es un control que simplifica el proceso.
Dentro del UpdatePanel está el <ContentTemplate> y dentro están dos controles Timer, uno actualiza la fecha y el otro la hora, uno está puesto para que actualice cada 2000 milisegundos y el otro cada 1000 milisegundos, osea 2 segundos y 1 segundo respectivamente. Podría haber sido solamente un Timer que actualice la fecha y la hora, pero se me ocurrió hacer 2 Timer y no tengo que andar explicando por qué, porque no tengo ganas.


Pero cómo es que actualiza la hora?
Bueno, eso le corresponde al código C# que está en ServerClockControl.ascx.cs
El método siguiente es el que se encarga de actualizar la fecha y la hora.
protected void TimerHora_Tick(object sender, EventArgs e)
{
 LabelHora.Text = DateTime.Now.ToString("hh:mm:ss");//ho.GetHora();

LabelFecha.Text = DateTime.Now.ToString("dd/MM/yyyy");// fe.GetFecha().Substring(0, 11);
}

Sí, tal cuál en Windows Form y en WPF, así, en LabelHora coloco el resultado de
DateTime.Now.ToString("hh:mm:ss"); en ese formato coloco hora, minutos y segundos, lo mismo va para la fecha, día, mes, año.
Finalmente queda así el control:

Gracias por leer!!! Yo soy Ger.
Bye!


Descarguen desde Codeplex, soy el usuario Becklespinax:
https://simpleajaxclockasp.codeplex.com/releases/view/101601

Proyecto en Codeplex:


domingo, 13 de marzo de 2016

MyIP (Programa para saber tu IP)

 Hola, un poco abandonado tengo el blog, hasta creo que le están saliendo tela de arañas...
 Este es el primer post de una serie de post que ya tengo casi escritos sobre programación.
 Acá va un artículo que escribí el año pasado y nunca publiqué, así que, disfruten... y si no lo disfrutan, me importa poco y nada.
Empecemos...
 Con el reciente cierre de GameSpy surgieron muchos inconvenientes a la hora de armar partidas on line de fórmula uno.
 El problema principal es que ya no pueden verse las partidas armadas, ese inconveniente planeo solucionarlo haciendo una web que muestre las partidas, pero por ahora no, en un futuro medio-lejano que quizás nunca llegue.
 Para armar partidas hay que usar algún sistema de redes como Hamachi, o en su defecto, quien arme una partida, debe pasarle la IP (Internet Protocol) de su conexión, así el que quiera unirse pueda hacerlo, pero surge aquí el inconveniente de los novatos: Cuál es mi IP?
 Cualquier usuario avanzado no duda mucho tiempo y enseguida lo obtiene yendo al panel de control de Windows o accediendo a múltiples páginas que se dedican a decirte cuál es tu IP.
Pero los usuarios novatos ni siquiera saben cuál es su IP, ni que es una IP, entonces decidí hacer este programita super simple en C# que les diga cuál es su IP en ese momento y tomo como base distintos métodos que he aplicado en  sistemas grandes que hice y que necesitaban saber la IP.

 Dividamos en 2 el trámite, por un lado está la IP Privada y por el otro, la IP pública. Para la IP privada vamos a usar la librería System.Net. Si el usuario usa un router, el métodos para saber la IP por medio de System.Net no va a servir, por qué? porque va a dar solamente la IP que asigna el router, que no es justamente la IP que le confiere el ISP al usuario que se conecta.

El Sistema está hecho en WPF (El que quiera lo puede hacer para Windows Forms), uso el compilador SharpDevelop.

Vayamos al grano:
La dll se llama MyIPFunction y posee la clase con el mismo nombre además de los siguientes métodos principales, que les transcribo a continuación con la explicaciónd e cada uno:

// Devuelve la IP Pública, la que requerimos para Jugar, para devolver la IP, uso la página //web "http://checkip.dyndns.org/"
LA IP PÚBLICA
private string sIPPublic(){
string s;
try
{
WebClient client = new WebClient();
// Add a user agent header in case the requested URI contains a query;
client.Headers.Add("user-agent""Mozilla/4.0 (compatible;"+
"MSIE 6.0; Windows NT 5.2; .NET CLR1.0.3705;)");

string baseurl = "http://checkip.dyndns.org/";

Stream data = client.OpenRead(baseurl);
StreamReader reader = new StreamReader(data);
s = reader.ReadToEnd();
data.Close();
reader.Close();

s=s.Substring(76);
s=s.Replace("</body></html>""").ToString();

}
catch (Exception)
{ s="0.0.0.0"; }
return s;
}

LA IP PRIVADA
// Devuelve la IP Privada , Listo todas las IP asignadas por el Router y verifico cuál es la mía
private string sIPPrivate()
{
sListIP=new List<string>();
NetworkInterface[] ni = NetworkInterface.GetAllNetworkInterfaces();// Listado de IP

//Después, las recorremos y las tratamos.
foreach(NetworkInterface n in ni)// No uso foreach mucho, pero acá sí
sListIP.Add(n.GetIPProperties().UnicastAddresses[0].Address.ToString());

IPHostEntry host;
string slocalIP = "";
host = Dns.GetHostEntry(Dns.GetHostName());
foreach (IPAddress ip in host.AddressList)
 {
 if (ip.AddressFamily.ToString() == "InterNetwork")
 {
 slocalIP = ip.ToString();
 }
 }
 return slocalIP;
}
 
DEVOLVIENDO LAS IP
Bien, ahora las IP las devuelvo con las siguientes funciones, que no debería tener necesidad de explicarlas, si necesitás que las explique, volvé a la escuela.

public string sGetIPPublic
{
get{return sIPPublic();}
}

public string sGetIPPrivate
{
get{return sIPPrivate();}
}

SI HAY ROUTER
Y por último, para saber si hay un Router o no conectado, basta con simplemente comparar las IP, la pública y la privada, si éstas son distintas, si son distintas, hay router, si son iguales, simplemente no hay router.
public bool bIsRouter(string ip1, string ip2)
{
return !ip1.Equals(ip2);
}

ENLACES
Que tengan buena vida y hasta el próximo capítulo, les dejo el enlace del código y su debug en mi dropbox.
https://www.dropbox.com/s/vhrk6fb1p07un8c/MyIP.rar?dl=0

sábado, 19 de julio de 2014

Simple programa para ver videos de youtube con Flash sin HTML5 y que no se corten al minimizar


Buenas noches.
Este mini post tiene el objetivo de solucionar un drama enorme que se viene sucediendo en los últimos tiempos con Youtube y HTML5. Conozco muchos casos, muchísimos, en los que antes podían escuchar música desde Youtube, minimizando la ventana del navegador y haciendo otra cosa en la computadora. Hoy en día, culpa de la actualización de Flash a HTML5 de los vídeos, esto se ha vuelto un poco tedioso, muchos vídeos entrecortan la música al querer hacer lo mismo que antes con Flash y en algunos casos hasta se tilda el navegador, lo que conlleva a emitir cientos de insultos a la computadora.
Todos culpan entonces que su computadora está lenta, pero no es tan así, en gran parte tiene que ver HTML5, Youtube por defecto usa el reproductor que viene incorporado en el nuevo estándar de este lenguaje y las etiquetas <video></video> sin, me parece, importarles que anda como el culo (Perdón la expresión, igualmente me importa poco si les molesta).
Bien, para resolver esto, decidí hacer un programita que reproduzca vídeos de Youtube pegando el link del mismo en un TextBox y usando Flash, como en viejas épocas.
Probando esto, vi que Flash descarga y reproduce los vídeos con mayor velocidad y ocupando muchos menos recursos, una joyita.
En Windows, ya vienen por defecto las librerías de Flash para reproducir vídeos, por si de casualidad no las tiene el ".rar" que acompaña este post la posee. Esta librería se llama AxInterop.ShockwaveFlashObjects.dll. La pueden agregar como referencia desde las COM no desde las NET cuando coloquen en Agregar Referencia.
Una vez agregada esta librería, deben agregar el control a las herramientas, porque casi seguro que no les va a aparecer. El control que les debe aparecer es como un panel, ese panel es donde se va a reproducir el vídeo. Si no les aparece en las herramientas coloquen en elegir elemento apretando botón derecho del Mouse sobre las herramientas y ahí elijan la misma dll que referenciaron.
Bien, entonces creamos un proyecto de Windows Form (me olvidaba decirles que iba a ser Windows Form). Luego referencien como les indiqué más arriba. Una vez obtenido el control, lo arrastran al Formulario, además arrastran un botón y un TextBox.
En el TextBox vamos a crear un evento KeyPress que va a tener la función de que cuando se presione enter se va a ir al vídeo que se indique, el botón va a tener el evento click que también va a realizar la misma función:

Los eventos mencionados son los siguientes:

private void ClickGo(object sender, EventArgs e)
{
vPlay();
}

private void PressEnter(object sender, KeyPressEventArgs e)
{
if(e.KeyChar==(Char)Keys.Enter)
{
vPlay();
}
}

Bien, como verán, ambos eventos ejecutan el método Play(), el método Play es el siguiente y más abajo explico cada cosa:

void vPlay()
{
smovie=TextBoxYoutube.Text;
vConvert();
FlashYoutubePlayer.Movie=smovie;
}

- smovie es un string que declaré globalmente (En el código que adjunto está).
- FlashYoutubePlayer es el nombre que le dí al control Flash agregado.
- vConvert() es una función que realiza una conversión del link de Youtube, veámosla:

void vConvert()
{
if(smovie.Contains("watch?v="))
{smovie= smovie.Replace("watch?v=", "v/"); }
}

Esta función quita del link "watch?v=" y lo reemplaza por "v/", esto hace que se eliminen las restricciones por país y se pueda reproducir cualquier vídeo. Se pueden hacer muchísimas cosas más, como agregar una base de datos que guarde los vídeos reproducidos, que los descargue y que guarde los links, además de otras cosas sobre el mismo control Flash, etc... Pero dejaremos esto para una futura versión... que quizás nunca llegue.

Va a tener muchas restricciones este mini programa, no les va a mostrar por ejemplo los vídeos recomendados de los costados, ni se va a poder presionar el "volver a la página anterior", sí les va a mostrar los vídeos recomendados al final del vídeo, pero el beneficio es que no se les va a cortar, va a andar rápido y ademas no te vas a tener que comer las propagandas malditas que te ponen estos desgraciados, es ideal para trabajar mientras se coloca una lista de reproducción de Youtube.

Yo lo compilé utilizando el Net Framework 2.0 para que ande en la mayoría de las computadoras, si quieren en las opciones pueden cambiarlo al .Net 4.0 que va a andar sin dramas. No incluyo el Net Framework en el instalador porque va a ser muy pesado. El instalador está hecho con ClickOnce, aunque prefiero mi querido Inno Setup con ISTool.

Bien, acá les dejo el código y el Instalador del mismo. Este lo hice en Visual Studio 2010.

Los que no son programadores, descarguen el instalador solamente.

Espero les sirva. Un saludo.

Código de YoutubePlayer

Instalador


viernes, 20 de junio de 2014

MySQL, PostgreSQL, Richard Stallman y la elección de una base de datos para nuestro sistema.

 La licencia GPL, la bendita licencia GPL o maldita mejor dicho para mí, es una tremenda trampa para quienes quieren hacer dinero con el software, una tremenda trampa es MySQL por usar esa licencia.
Hasta hace un tiempo, un jefe de una empresa importante de software me dijo que uno podía usar MySQL con fines comerciales y dentro de productos con código privativo sin pagar un solo centavo a Oracle, que es la actual dueña de MySQL (todo el mundo sabe que compró SUN Microsystem antigua dueña de MySQL para limitar el desarrollo de ésta Base de Datos y destruir su competencia, aparte de hacerse con los derechos de JAVA, el supuesto lenguaje libre (que de libre no tiene nada)), dijo que sólo habría que pagar si se le pedía soporte o se reformaba el código. No sé que pasará para los desarrollos ya hechos con MySQL, pero la verdad es que este jefe estaba equivocado, completamente, hay que ser estúpido para ser director y no saber la verdad del asunto, debería dejar su cargo ya que por su culpa, esta empresa se podría comer decenas de juicios.

 La verdad de la milanesa es que si de verdad querés ganar plata con un sistema, éste no deberá ser open source. Me van a decir que Google y Facebook hacen todo open source, bien, entonces que te den el código fuente de su buscador y de su red social respectivamente, ya que todo es open source. Critican a Microsoft por usar licencia privativa en su producto Windows, pero como Windows es su principal producto, al igual que la red social para Facebook y el buscador para Google (que como dije, no entregan su código fuente), entonces por qué Microsoft es el demonio y los otros los santos? Con esto no quiero decir que Microsoft sea santo, quiero decir que los otros están a su mismo nivel.

 Luego está el caso de Apple, que tiene todo privativo pero está como "santificado", quién sabe por qué, si casi todo lo que hace es privativo.

 Y después está Richard Stallman, acérrimo defensor del open source, llevando luces de fuegos de artificio y haciendo creer que todo sería un paraíso si todos los sistemas fueran open source. Si esto fuera así, a los programadores nos convendría poner una verdulería o ir a trabajar de cartoneros.

 Richard Stallman, alias la máquina de criticar, dice lo siguiente de cada lenguaje y empresa:
Java: Decía que había inseguridad y que no era open source, por lo tanto, que no usen Java.
C++: Decía que era un mal diseño, que no lo usen tampoco.
C#: Decía que si Microsoft cambia su licencia, estamos fritos todos los programadores. Así que no había que usarlo.
Windows: Que sus usuarios están presos y que es una porquería como Microsoft.
Apple: Que es peor que Microsoft.
Linux: Que arruinó el GNU y que culpa de Linus Torvals no lograron el núcleo propio y demás cosas contra Linus y Linux.
Si fuera por él, sólo habría que usar Lisp y Unix, eso y morirnos de infelices, es lo mismo.

 Soy usuario de software libre y creador de software libre, pero hay límites, límites que Richard no los tiene y critica todo lo que se le cruza sin pensar que él usa o usaba una notebook (usaba porque se la robaron, habrán dicho "es open source" y me la llevo) que no permitía instalar software privativo, siendo que esa misma restricción, impide al usuario de hacer la principal ley del open source, que es hacer lo que se quiera con lo que se compra o adquiere.

 Este post tiene un rápido análisis de las bases de datos existentes y de cuál es la indicada para hacer un sistema de doble licenciamiento (GPL y Privativo) el cuál deberá poseer conectores ADO.Net para la plataforma .NET, en cuyo caso la base de datos no tenga costo alguno:

Barajé algunas posibilidades, que son en resumen, bases de datos conocidas y con las que trabajé varias veces y a continuación detallo los resultados:

SQLServer: Esta base de datos es propiedad de Microsoft, es de código privativo y tiene una versión express totalmente funcional con algunas limitaciones con respecto a la versión completa, como 4GB de tamaño máximo por base de datos, uso de un sólo núcleo de preprocesador. La versión completa encarece demasiado el  proyecto, además de la posibilidad de una futura versión Linux, Android, Mac/OS e IOS hicieron que descartara su uso por el trauma que significaría una migración a otra base de datos compatible con los otros sistemas operativos, no ocurriría lo mismo con otras soluciones privativas de Microsoft como el caso de Microsoft Solver y Microsoft Sync Framework, que usaría en el proyecto y que mudaría de sistema operativo gracias a Xamarín y la plataforma Mono, en cuyo caso  simplemente con cambiar de librería se solucionaría el problema de migración. Por otro lado la versión Express es poco clara con respecto a su uso, pudiendo ser objeto de sanciones legales.


MySQL: Este motor de bases de datos es el más usado en el mundo, extremadamente rápido para aplicaciones incluso de gran tamaño, fácil de usar y de configurar con las características que pueden usarse triggers, funciones, backups, replicación, uso de algunas herramientas excelentes como MySQL WorkBench y Mysql Administrator. Actualmente es propiedad de Oracle que lo heredó al comprar Sun Microsystem, su antigua dueña. Parecía ser la solución perfecta ya que trabajé en esta base de datos la mayoría del tiempo, incluso la estructura de datos (Modelo Entidad-Relación) para este proyecto la realicé en MySQL WorkBench con la predisposición de  usarla casi convencido. En lo apresurado del título "Gratis" que tiene MySQL, obvié algunos conceptos de lo que significa la licencia que posee, la GPL (General Public License). El doble licenciamiento que pretendo darle al producto (Licencia Privativa y Licencia Compatible con la GPL versión 2) hubiese implicado una posible demanda por parte de Oracle si no adquiría  una versión comercial para cada producto vendido con licencia privativa, esto encarecía en 2 mil pesos por unidad de producto debiendo cargar con los costos el cliente y si usare la parte cliente (esto iba en contra de una de las ventajas que va a tener el software en donde no se pretende cobrar por cada copia de acceso a datos en modo Cliente desde tablets, smartphones y otras pcs), también debía pagar por la misma para no tener posibles problemas legales con Oracle, pasando de 6 mil pesos a 8 mil pesos aproximadamente por unidad servidora el producto en su costo total y otros 2000 mil pesos por unidad Cliente, lo cual desanimaría a los clientes que compraran el producto en cuanto al precio. Es de suponer que la licencia privativa será más barata que la open source, pero este tipo de licenciamiento al tener un costo elevado, muy pocos verán con buenos ojos comprarlo (por más verso que haya sobre el Open Source).
La Licencia GPL busca asegurarse que todo software que incluye una parte  GPL, debe ser también GPL, ya que se considera software "derivado" y si esto no fuera así, no cumpliría los términos de la GPL dando lugar a juicios por patentes.

MariaDB: Del mismo creador de Mysql, proporciona total compatibilidad con esta última es  más rápida y con novedades que la mejoraban considerablemente, pero  esto es casi lo mismo ya que su licencia también es GPL, con la diferencia que si se usa como cliente (conectores que acceden a  la BD) la licencia es LGPL (Lesser General Public License) con permiso para poder incluirla en software privativo sin tener que pagar, igualmente quedaba lo de tener que pagar por la licencia servidora para la licencia privativa. Queda entonces descartada por lo mismo que MySQL.

PostgreSQL: Posee una licencia BSD (Berkeley Software Distribution), incompatible con GPL ya que este permite poder usar la base de datos en una aplicación privativa, pudiendo distribuir en el mismo instalador a PostgreSQL gratis sin tener restricciones por patentes ni licencias, con la  única obligación de de acompañar la distribución con un archivo ".txt" que indica los permisos de la misma. Además es la mejor opción por versatilidad (compite con la base de datos Oracle y es más robusta que MySQL, además de que puedo modificarla, venderla y nunca depender de una empresa como  en el caso de MySQL o SQLServer). PostgreSQL es la indicada, además de que un sin número de servidores la apoyan en el mundo y está en constante progreso con su variedad de colaboradores y su seguridad que a todos sorprende.

SQLite: Esta base de datos no es Cliente - Servidor, no posee un proceso activo a la espera de recibir y enviar información. Es muy rápida, he realizado algunos trabajos para este motor. La gran desventaja que tiene los otros motores con este otro, es que no pueden usarse en smartphones o tablets que requieren ahorro de energía, IOS, Android, Windows Phone y RT difícilmente puedan  contener a PostgreSQL o MySQL. El objetivo no es usarla como base de datos principal sino, como base de datos que sirva para la replicación o sincronización en conjunto con PostgreSQL.

CONCLUSIÓN:
 PostgreSQL con SQLite son las indicadas. En el caso de PostgreSQL la he probado guardando imágenes y toda clase de archivos en formato bytea y anda espectacular (las guardo en distintos tamaños de previsualización e hice algoritmos que cuando crece la bd hasta cierto punto, cree una nueva bd), soy defensor total de que hay que guardar todo en la base de datos (no la ruta, todo el archivo) y cuyo análisis y experiencia sobre el tema lo dejo para otro post. MySQL también es bárbara y también la probé guardando imágenes en formato blob y mediumblob y anda fenomenal con el manejo de imágenes y archivos en general, pero muere con su licencia GPL.
 PostgreSQL es un mundo, hay de todo lo imaginable y lo inimaginable, es cuestión de ponerse, aunque acepto que lleva más tiempo trabajar con PostgrSQL que con MySQL.

Espero haber aclarado dudas y que les sirva mi análisis. Saludos.

lunes, 24 de septiembre de 2012

Lo que extraño de C++


Hola:
         Hoy quiero comentarles algunos choques que tuve cuando me enfrenté a C# viniendo del mundo C++, las cosas que extraño, aunque reconozco que no son muchas, ya que C# realmente tiene innumerables beneficios y por eso hoy es mi lenguaje favorito (no sé mañana).
       
Extraño de C++:

- Las STL: Significan Standar Template Library y traen un conjunto de clases realmente útiles. Tiene una serie de contenedores y los que mas he usado han sido la clase vector (que es como un array pero con métodos que te simplifican la vida), list y deque, sobre todo el deque, ya que este internamente funciona como un list, pero con la sintaxis de un vector, es decir, no necesita iteradores para recorrerse como el list y por lo tanto su sintaxis es menos tediosa. Por qué esto es importante, porque un vector ocupa siempre un bloque de memoria contiguo, es decir que si no hay un bloque de memoria contiguo, se producirían errores, un fallo de memoria o el sistema alertaría de que no hay memoria, es difícil que ocurra hoy con las máquinas que existen, pero pensemos en grandes volúmenes de datos que extraemos de una base de datos y queremos colocarlos en una grilla, si falta memoria, se produce un error, ahí es donde entran en juego los list y los deque, los mismos buscan los lugares vacíos que no necesariamente tienen que ser contiguos. Lo mas parecido a las STL son las Generics de C# en donde la mas usada es la clase List, pero extraño las STL porque hice muchos trabajos con las mismas y por ende les había agarrado la mano. Iguál las Generics no sólo las reemplazan, sino que mejoran en muchos aspectos.

- Tirar una "funcioncita" al aire: Cuando tengo que hacer un método de una clase que a su vez debería usar en varias clases, es ahí donde digo "volvé C++" (hasta que lo pienso mejor) porque en C# o debo hacer una clase especialmente e instanciarla luego o debo crear una Interfaz que contengan su definición y heredar en la clase la misma o bien hacer un método en cada clase que haga lo mismo. Siempre preferí tener una función que haga tal cosa y tenerla en un archivo .h que coloco como cabecera y poder llamarla desde cualquier recóndito rincón de código sin muchos tapujos. Yo sé que los programadores orientados a objetos extremistas me van a pegar el grito en el cielo debido a que va en contra del nuevo orden mundial de programación, pero yo prefiero no ser "extremista" cuando los tiempos te comen, en estos casos se necesita ser "simplista".

- La herencia múltiple: Como todos saben tanto Java y C# no permiten herencia múltiple, sí permiten herencia simple entre clases y múltiples herencias desde Interfaces. Podrán decir que se reemplaza la herencia múltiple con herencias de herencias, es decir un nieto, puede acceder a su padre y su padre a su padre, entonces el nieto puede acceder a su abuelo también, pero en C++ uno heredaba desde donde quería, lo que quería. Es cierto que si existían dos métodos entre las clases que se heredaban que eran iguales, traía inconvenientes, pero si se sabía usar era muy pero muy útil.

- Las etiquetas public, private y protected: Cuando uno creaba métodos en las clases o atributos uno simplemente hacía:
public:
void funcion();
void talcosa();
int a;
private:
int b;
void talotra();

y de esta manera lo que estaba debajo de cada etiqueta era o private o public, en cambio en C# hay que colocarle qué nivel de privacidad va a tener a cada uno de los atributos y métodos:


public void funcion(){}
public void talcosa(){}
public int a;
private int b;
private void talotra(){}


Seguiré modificando este post para ir agregando cosas que extraño de C++, igualmente repito que son muchos más los beneficios que dá C# y que contaré en un post siguiente...


Instalación de PostgreSQL en forma desatendida desde C#

  Hola:
  Este va a ser el primer post de una serie de post para PostgreSql con c#.
  En esta oportunidad me voy a centrar en la instalación desatendida y en algunos
inconvenientes que han surgido y que supe superar.
  En los sucesivos post, explicaré cómo conectar,crear una base de datos y tablas desde C#
con PostgreSQL, debido a que vi muy poco material sobre esto ya que la mayoría te enseña a
conectar PostgreSQL con C# y te dicen que hagas las tablas en pgAdmin o desde la línea de
comandos, esto estaría bien si fuese yo solamente quien va a usar la aplicación o si
nosotros vamos a instalarle al cliente el sistema, pero si queremos hacer una aplicación
para distribuir en masa, no le vamos a pedir a nuestro cliente que haga ese trabajo que debería
hacer nuestra aplicación sin la menor intervención de él, sería como que me vendieran un
auto nuevo y me pidan que yo me encargue de armar el motor.
  Me adelanto a que seguramente van a surgir muchos que ofrezcan mejores soluciones, serán
bienvenidas por supuesto, yo lo que voy a escribir es algo probado por mi, espero que
quienes sugieran otra cosa, den prueba de que lo de ellos ha funcionado.
  Cuando uno hace un instalador, puede empaquetar el .exe instalador del motor de la bd, y
ejecutarlo en el mismo instalador de la aplicación, siguiendo la misma línea de comando que
voy a usar para C#, será cuestión de gustos. A mi me gusta preguntar desde C# si será una
instalación que hará de Cliente o que hará de Servidor. La diferencia es que si es Cliente
no necesariamente hay que instalar PostgreSQL, solamente hay que instalar su conector.
  Algún que otro experto en instaladores podrá saltar y decir muchas cosas que darán por
hecho, pero yo prefiero ser experto en C# y no tanto en instaladores.


Detalles y discusiones previas:

  La versión de PostgreSQL que voy a usar es la 9.2 y se la puede descargar desde esta
dirección: http://www.enterprisedb.com/products-services-training/pgdownload#windows
Allí eligen la mas común que es la versión para Win x86-32, obvio que si tienen un Windows
de 64 bits, deben elegir la otra opción.
Esta versión posee un instalador distinto a la de la versión 8.3 que era un instalador msi
y cuyas opciones de instalación son otras a las que se presentan a partir de la versión
8.4. Les recomiendo que usen la misma versión que yo, porque si les surgen inconvenientes
al menos se descartará que sea por culpa de una versión diferente.
  Una vez descargado, pueden probar si quieren instalarla en forma normal para ir viendo las
opciones, este post sólo tiene el objetivo de instalar en forma desatendida.
En algunos windows de algunas máquinas (sobre todo en windows machacados, de esos que hay
que reinstalar urgentemente) al instalar en forma normal, tiraba algunos errores y no se
terminaba instalando PostgreSQL, estos errores eran con el instalador de EnterpriseDB, no
había dramas con los instaladores msi para la versión 8.3, quizás en esos windows
machacados faltaba algún archivo o algo pasaba que realmente desconozco, pero al instalar
en forma desatendida, se instalaba perfectamente.
  Usaré además el excelente IDE SharpDevelop 4.2.

Instalando desde la línea de comandos:
  Antes que nada les muestro como sería instalar desde la línea de comandos de windows.

A continuación les presento las opciones de instalación que existen en
PostgreSQL 9.2:

--help                         Display the list of valid options
--version                      Display product information
 --unattendedmodeui <unattendedmodeui> Unattended Mode UI
                                Default: minimal
                                Allowed: none minimal minimalWithDialogs
 --optionfile <optionfile>      Installation option file
                                Default: 
 --debuglevel <debuglevel>      Debug information level of verbosity
                                Default: 2
                                Allowed: 0 1 2 3 4
 --mode <mode>                  Installation mode
                                Default: qt
                                Allowed: qt win32 unattended
 --debugtrace <debugtrace>      Debug filename
                                Default: 
 --installer-language <installer-language> Language selection
                                Default: en
                                Allowed: en es fr
 --extract-only <extract-only>  
                                Default: 0
 --superaccount <superaccount>  Sets the user name of the database superuser. Defaults to 
'postgres'.
                                Default: postgres
 --servicename <servicename>    Sets the name of the database service.
                                Default: 
 --serviceaccount <serviceaccount> Sets the operating system user account that owns the 
server process. Defaults to 'postgres'.
                                Default: 
 --servicepassword <servicepassword> Sets the password for the operating system user 
account that owns server process. Defaults to superuser password.
                                Default: 
 --install_runtimes <install_runtimes> Specifies whether or not install the Microsoft 
Visual C++ runtimes before the installation proceeds.
                                Default: 1
 --create_shortcuts <create_shortcuts> Specifies whether or not menu shortcuts should be 
created.
                                Default: 1
 --prefix <prefix>              Installation Directory
                                Default: C:\Archivos de programa\PostgreSQL\9.2
 --datadir <datadir>            Data Directory
                                Default: C:\Archivos de programa\PostgreSQL\9.2\data
 --superpassword <superpassword> Password
                                Default: 
 --serverport <serverport>      Port
                                Default: 5432
 --locale <locale>              Locale
                                Default: 

  Desde la linea de comandos se instalaría de la siguiente manera suponiendo que al archivo
instalador le dejé el mismo nombre con el que se descarga y el mismo se encuentra en el directorio raíz de windows:
C:\>postgresql-9.2.0-1-windows.exe --mode unattended --superpassword mipass  
--servicepassword mipass --serverport 5434 --unattendedmodeui none  --prefix 
C:\PostgreSQL\9.2 --datadir C:\PostgreSQL\9.2\Data
     
--mode unattended: Significa que será en modo desatendido.
--prefix C:\PostgreSQL\9.2: Significa que voy a instalar la base de datos en el directorio
C:\PostgreSQL\9.2, es decir que cambio el que viene por defecto  que es C:\Archivos de
programa\PostgreSQL\9.2\data.
--datadir C:\PostgreSQL\9.2\Data: Instalo los datos en el directorio C:\PostgreSQL\9.2\data en
lugar del que viene por defecto que es C:\Archivos de programa\PostgreSQL\9.2\data.
--serverport 5434: Uso el puerto 5434 y no el que viene por defecto que es el 5432 (si quieren dejen el por defecto que es l que se usa mas comunmente).
--unattendedmodeui none: Le digo que no muestre ni siquiera la ventana mínima.
--superpassword mipass: Establece el password que en este caso será "mipass". Si no colocan esto el pass por defecto será "postgres".

  También puede colocarse otras opciones como --install_runtimes en donde colocando 0 se le
dice que no instale los runtime  visual c++ que necesita para funcionar, pero lo conveniente es
dejar lo que viene por default, osea 1, por si la máquina en que se va a instalar no lo
posee.


Instalando desde C#:
  Primero creo una clase, esta clase se va a llamar InstalacionPostgreSQL y va a tener dos métodos, uno que se va a llamar "Instalar" y va a devolver un bool y el otro se va a llamar "ComprobarSiExiste" que va a devolver un booleano que si es true significa que existe, sino, no existe, este método lo que hace es buscar la clave del registro de PostgreSQL.
  El ejecutable de la instalación de PostgreSQL en esta oportunidad va a estar dentro de la carpeta Installers que vamos a tener dentro de la carpeta donde se encuentra el ejecutable de nuestra aplicación en C#.
  Es recomendable colocar una barra de progreso en una ventanita cosa de mostrarle al cliente que se está instalando algo, debido a que tarda un poco y el cliente puede pensar que la máquina se tildó o algo por el estilo.
 A continuación la clase instaladora:

//Dos espacios de nombres que se van a usar, uno sirve para ejecutar procesos y el otro
//para leer claves en el registro
using System.Diagnostics;
using Microsoft.Win32;

public class InstalacionPostgreSQL  //Nombre de la clase
 {
public InstalacionPostgreSQL() //Constructor sin parámetros
{}
public bool Instalar()  //Función que instala PostgreSQL
{
//Paso al string la ruta del ejecutable de nuestra aplicación
string ruta=Application.StartupPath;
//Le paso que el directorio por defecto sea el del ejecutable
Directory.SetCurrentDirectory(ruta);

//En los siguientes strings indico los parámetros y qué archivo se ejecuta
string installerpostgre=@"--mode unattended --superpassword mypass  --servicepassword mypass --serverport 5434 --unattendedmodeui none  --prefix C:\PostgreSQL\9.2 --datadir C:\PostgreSQL\9.2\Data";
string x="Installers\\postgresql-9.2.0-1-windows.exe";

Process oProc = new Process();//Creo el proceso
try //Con este try catch atrapo cualquier excepción que se produzca
{
oProc.StartInfo.RedirectStandardInput = true;
oProc.StartInfo.RedirectStandardOutput = true;
oProc.StartInfo.CreateNoWindow=true;//Le indico que no debe abrir la típica ventana DOS cuando           ejecuto el proceso
oProc.StartInfo.UseShellExecute = false;
oProc.StartInfo.FileName = x;//Le indico que debe ejecutar el archivo del path que se encuentra en este string
oProc.StartInfo.Arguments = installerpostgre;//Le paso los parámetros que contiene este string
oProc.Start();//Comenzar el proceso
oProc.WaitForExit();//Esperar a que termine el proceso para terminar
oProc.Close();//Cierro el proceso
}
catch{
return false;//Si hubo error, retorno false 
}

MessageBox.Show("Se ha instalado PostgreSQL 9.2.");//Aviso que se instaló correctamente

return true;//Retorno true para que se sepa que se instaló correctamente
}

bool   ComprobarSiExiste()
{
string clavreg=@"SOFTWARE\PostgreSQL\Installations\postgresql-9.2";
 // Abrimos la clave del registro con la que queremos trabajar
RegistryKey rk1 = Registry.LocalMachine;
// Nos movemos hasta la subclave donde queremos trabajar.
// El parámetro boleano indica si la abrimos en solo lectura (false)
// ó en lectura/escritura (true).
rk1 = rk1.OpenSubKey(@clavreg,true);
// Si devuelve null es que la clave no existe
if (rk1 == null)
   return  false; //No existe entonces retorno falso
else
return  true;//Existe entonces retorno verdadero
}

}//Fin de la clase


                       Errores con los que me topé:

  Asegúrensen de tener el editor del código de SharpDevelop en fuente tipo Unicode como puede ser Arial Unicode MS porque puede mal interpretar los dos guiones seguidos "--" y a uno interpretarlo como otro carácter, es por eso que si le aparece un cartelito que les indica en inglés que se fije en la ayuda del instalador, prueben cambiar la fuente del editor yendo a Herramientas-Opciones-Editor de Texto de SharpDevelop y allí cambiar dicha fuente. Ahora lo cuento como algo sencillo pero estuve bastante para saber que era eso tan simple.
  Investigando en instalaciones de PostgreSQL 9.2 me he topado con que muchos en lugar de
colocar --serverport, colocan --port o mas adelante cuando se vea creación de base de datos PostgreSQL 9.2 y creación de tablas, para realizar la conexión colocan --server en lugar de --host, esto tiene como resultado que no se instala PostgreSQL 9.2 ni se crea ni la base de datos y por supuesto, tampoco las tablas. Ojo! en la "Conexión" a PostgreSQL 9.2 una vez instalada ésta, sí hay que usar --port en vez de --serverport, ignoro por qué lo hicieron así, pero en la "Instalación Desatendida" es al revés. Otro es que en lugar de --superpassword vi post que colocan --user o --user id, esto tampoco sirve, no se instala y en el caso de la creación de base de datos y tablas, tampoco sirve, porque ahora se usa --username.


                              Ejemplo de Aplicación:

  Supongamos que ya tenemos los formularios o una ventana WPF de una Agenda que va a Funcionar con PostgreSQL (Es un desperdicio usar PosgreSQL para una agenda, convendría usar algo como SQLite, pero aquí es a modo de ejemplo).
  Usando la clase InstalacionPostgreSQL podríamos hacer algo así:

public partial class Agenda : Window
{
#region {Globals Variables}
InstalacionPostgreSQL InPostgre=new  InstalacionPostgreSQL ();  //Creo un objeto de la clase
#endregion {Globals Variables}

#region {Constructor}
public Agenda()
{
InitializeComponent();//Cargo los componentes de la agenda, que puede ser una Datagrid o cualquier //elemento que uno haya colocado en el WPF

if(!InPostgre.ComprobarSiExiste()) //Pregunto si no existe PotgreSQL
{
//Si no existe instalo
InPostgre.Instalar();

}
}
#endegion {Constructor}
 }//Fin clase