Blog de Francisco Velázquez

otro blog personal

Ajustar resolución en Warcraft3

leave a comment »

Abrir el registro de windows y editar las siguientes claves en:

HKEY_CURRENT_USER\Software\Blizzard Entertainment\Warcraft III\Video

resheight (defecto: 768) y reswidth (defecto: 1024)

via.

Written by fravelgue

August 3, 2011 at 5:10 pm

Posted in personal

Tagged with

Consultas en SQL Server con IN

leave a comment »

Al hacer una consulta de este estilo:

SELECT …. WHERE campo NOT IN (…)

No va a incluir las tuplas cuyo campo sea NULL. Por tanto si queremos incluirlos, habrá que indicarlo explícitamente:

SELECT …. WHERE campo NOT IN (…) OR campo IS NULL

Written by fravelgue

August 2, 2011 at 5:56 pm

Posted in development

Tagged with , ,

¿Avanza el software tan rápido?

leave a comment »

En el mundo de la computación y software parece que todo va muy muy rápido. Así que pensamos que la tecnología lleva un camino de avance cada vez más rápido y sin vuelta atrás. Sin en embargo leyendo el blog Eureka, me he planteado si realmente esto no es pura impresión y en realidad el software no es ajeno a la vida y sigue su ritmo.

Leyendo este blog y la trayectoria del transbordador espacial, parece que no todo va tan rápido y que para conseguir algo son necesarios varios decenios. En el mundo del software aunque parece que el ritmo de desarrollo es desenfrenado, si miramos a los sistemas y software de los 5060-70 podemos comprobar que, tal vez, no hayamos avanzado tanto. Y las soluciones que se daban en muchos casos eran igual de válidas que las actuales.

Si un humano necesita 10 años para considerarse un experto en algo, como no van a ser necesarias muchas décadas para que cualquier tecnología termine siendo aceptada.

Tal vez este tipo de conceptos sean muy necesarios en el desarrollo de software para así construir sistemas que perduren por muchos años.

PS A pesar de no haber tenido nunca especial interés por la astronomía, el blog de Daniel Martín me parece uno de los mejores que leo y un descubrimiento reciente, y esto era simplemente una excusa para poder enlazarlo 😉

Written by fravelgue

August 2, 2011 at 4:11 pm

Posted in personal

Simple cache para BusinessObjects

leave a comment »

Debido a la naturaleza de mi trabajo, aplicaciones multitenant, y servicios M2M, para mejorar el rendimiento suelo cachear muchos objectos que tienen un tasa de lectura muy alta y de cambios muy muy pequeño. Así que para facilitar el trabajo, me he decido crear una pequeña utilidad.

    /// <summary>
    /// Concurrent cache for BusinessObject.  It doesn´t clean cache, useful for small data.
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class BusinessObjectCache<T>
        where T : BusinessObject<T>
    {
        static ReaderWriterLockSlim Locker = new ReaderWriterLockSlim();
        static volatile Dictionary<object, T> storage;

        static BusinessObjectCache()
        {
            Locker.EnterWriteLock();
            try
            {
                storage = new Dictionary<object, T>();
            }
            finally { Locker.ExitWriteLock(); }
        }

        public T Get(object id)
        {
            T o = null;
            Locker.EnterReadLock();
            try
            {
                if (storage.ContainsKey(id))
                {
                    o = storage[id];
                    return o;
                }
            }
            finally { Locker.ExitReadLock(); }

            if (o == null)
            {
                Locker.EnterUpgradeableReadLock();
                try
                {
                    if (!storage.ContainsKey(id))
                        o = BusinessObject<T>.Retrieve(id);

                    if (o != null)
                    {
                        Locker.EnterWriteLock();
                        try
                        {
                            storage[id] = o;
                        }
                        finally { Locker.ExitWriteLock(); }
                    }
                }
                finally { Locker.ExitUpgradeableReadLock(); }
            }

            return o;
        }
    }

A ver si me lo curro y la hago LRU.

Written by fravelgue

July 21, 2011 at 5:44 pm

Posted in development

Tagged with , ,

Simple HTTP GET en C#

leave a comment »

La verdad es que, a veces, cosas sencillas se hacen  complicadas en .NET y en mi opinión esta es una de ellas. Nada que objetar a que un framework tiene que ser lo menos restrictivo posible, pero en este caso no encuentro el sentido de que un error HTTP tenga que lanzar una excepción, yo personalmente la definiría como excepción vexing. Y bueno como estamos para ayudar pues con esta pequeña función todo será un poco más sencillo.

        public static int Get(string uri, int timeout, out string response)
        {
            int statusCode = -1;
            response = string.Empty;

            HttpWebRequest request = WebRequest.Create(uri) as HttpWebRequest;
            request.KeepAlive = false;
            request.Timeout = timeout;

            try
            {
                using (HttpWebResponse res = (HttpWebResponse)request.GetResponse() as HttpWebResponse)
                {
                    statusCode = (int)res.StatusCode;
                    using (Stream dataStream = res.GetResponseStream())
                    {
                        using (StreamReader reader = new StreamReader(dataStream))
                        {
                            response = reader.ReadToEnd();
                        }
                    }
                }
            }
            catch (WebException wex)
            {
                //http://msdn.microsoft.com/en-us/library/es54hw8e.aspx
                if (wex.Status == WebExceptionStatus.ProtocolError)
                {
                    // If status is WebExceptionStatus.ProtocolError,
                    // there has been a protocol error and a WebResponse
                    // should exist. Display the protocol error.
                    using (HttpWebResponse res = wex.Response as HttpWebResponse)
                    {
                        if (res != null)
                        {
                            statusCode = (int)res.StatusCode;

                            using (Stream s = wex.Response.GetResponseStream())
                            using (StreamReader reader = new StreamReader(s))
                            {
                                response = reader.ReadToEnd();
                            }
                        }
                        else
                        {   // no http status code available
                            throw wex;
                        }
                    }
                }
                else
                {   // no http status code available
                    throw wex;
                }
            }

            return statusCode;
        }

Cuanto más veo ese código, menos me gusta como está diseñado.
Un par de enlaces.

Written by fravelgue

July 19, 2011 at 7:27 pm

Posted in development

Tagged with , , , , ,

DAOs sobre Dapper

leave a comment »

La verdad es que los micro-ORMs están de moda (Massive, Dapper, PetaPOCO, SimpleData, etc). Basándome en esta abstracción y en mi querido Gentle.NET, me he decido a construir unos DAOs sobre Dapper, que es usado en Stackoverflow, y como características principales podemos decir: que es fuertemente tipado con una interfaz muy clara, y como extra soporta operaciones asíncronas a DB.

Creo que la mejor manera de entender el funcionamiento es con un ejemplo:

    class Example
    {
        class Message
            : BusinessObject<Message>
        {
            [PrimaryKey]
            public Guid Id { get; set; }
            public string DestinationAddress { get; set; }
            public string SourceAddress { get; set; }
            public string UserData { get; set; }
            public int Ton { get; set; }

        }

        public void Example1()
        {
            Message m = new Message()
            {
                Id = Guid.NewGuid(),
                DestinationAddress = "34612345678",
                SourceAddress = "404",
                UserData = "Example 01",
                Ton = 1
            };

            m.Insert();

            List<Message> l = Message.FindBy(new SqlCondition("DestinationAddress", Operator.Equals, "34612345678"));

            m.Remove();
        }
    }

A continuación mostraremos el código de las funciones básicas de CRUD.

    public class BusinessObject<T>
        where T: class
    {
        public static SqlConnection GetConnection()
        {
            return ConnectionFactory.Create(typeof(T).Namespace);
        }

        public static T Retrieve(object id)
        {
            string sql = string.Empty;
            DynamicParameters p = new DynamicParameters();
            p.Add(GetPrimaryKey(), id, null, null, null);
            StringBuilder sb = new StringBuilder()
                .AppendFormat("select * from {0} where {1} = @{1}", GetTableName(), GetPrimaryKey());
            return queryInternal(sb.ToString(), p).FirstOrDefault();
        }

        public void Insert()
        {
            string sql = string.Empty;
            DynamicParameters p = new DynamicParameters();
            StringBuilder columns = new StringBuilder(), values = new StringBuilder();
            bool first = true;

            foreach (string prop in GetProperties())
            {
                if (first)
                {
                    columns.AppendFormat("{0}", prop);
                    values.AppendFormat("@{0}", prop);
                }
                else
                {
                    columns.AppendFormat(", {0}", prop);
                    values.AppendFormat(", @{0}", prop);
                }
                p.Add(prop, getPropertyValue(this, prop), null, null, null);
                first = false;
            }

            sql = string.Format("insert into {0} ({1}) values ({2})",
                GetTableName(), columns.ToString(), values.ToString());

            int res = executeInternal(sql, p);
        }

        public void Update()
        {
            // ... 
        }
        public void Remove()
        {
            // ...
        }

        public static List<T> FindBy(SqlCondition[] conditions)
        {
            DynamicParameters p = new DynamicParameters();
            StringBuilder sb = new StringBuilder()
                .AppendFormat("select * from {0} where", typeof(T).Name);

            bool first = true;
            int i = 0;
            foreach (SqlCondition c in conditions)
            {
                // for multiple conditions with same column
                string var = c.PropertyName + (i++);
                if (!first) sb.Append(" AND");

                if (c.Value == null)
                {
                    sb.AppendFormat(" {0} {1} NULL", c.PropertyName, OperatorHelper.ToString(c.Operator));
                }
                else
                {
                    sb.AppendFormat(" {0} {1} @{2}", c.PropertyName, OperatorHelper.ToString(c.Operator), var);
                    p.Add(var, c.Value, null, null, null);
                }
                first = false;
            }

            return queryInternal(sb.ToString(), p);
        }

        protected static List<T> queryInternal(string sql, object param)
        {
            List<T> l = null;

            using (var conn = GetConnection())
            {
                try
                {
                    conn.Open();
                    l = conn.Query<T>(sql, param, null, false, 0, null).ToList();
                }
                finally { conn.Close(); }
            }

            return l;
        }

Faltaría algo de código para representar las condiciones SQL, así como algunas funciones que usan reflección para optener el nombre de la tabla, propiedades o clave primaria.

Written by fravelgue

June 27, 2011 at 8:11 pm

Posted in development

Tagged with , ,

La SIM, una ventaja de las operadoras

leave a comment »

En el blog de cmt, se hacen eco de las intenciones de Apple para intentar liberarse de las operadoras. En mi opinión los operadores debería aprovechar esta ventaja e integrar más funcionalidad en ese chip, como por ejemplo, incluir RFID para posibilitar micro-pagos.

Written by fravelgue

June 16, 2011 at 10:03 pm

Posted in mobile

Tagged with , ,

Deserializar en C# ignorando DTD

leave a comment »

        public static object Deserialize(System.Type type, string data)
        {
            XmlSerializer xmlSerializer = new XmlSerializer(type);
            TextReader textReader = new StringReader(data);
            XmlReaderSettings settings = new XmlReaderSettings();
            settings.ProhibitDtd = false;
            settings.XmlResolver = null;
            XmlReader xmlReader = XmlTextReader.Create(textReader, settings);
            return xmlSerializer.Deserialize(xmlReader);
        }

Written by fravelgue

June 8, 2011 at 9:48 am

Posted in development

Tagged with , , ,

Agregar o quitar programas

leave a comment »

Ir a agregar o quitar programas en windows: Win+R -> “appwiz.cpl” -> Enter

via.

Written by fravelgue

May 30, 2011 at 8:59 pm

Posted in util

Tagged with

#nolesvotes

leave a comment »

A este pobre blog no lo visitan ni los robots de los buscadores, pero así y todo no quería dejar de enlazar.

Written by fravelgue

May 18, 2011 at 5:31 pm

Posted in personal

Tagged with

Design a site like this with WordPress.com
Get started