viernes, 30 de noviembre de 2007

¿Tengo Internet? System.Net.WebResponse.

Metiéndome en berenjenales para practicar con las clases de la librería system.net me propuse hacer una pequeña aplicación que me indique cuando los "magos" de sistemas me cortan internet.

Primero pensé en un Ping, pero me he encontrado que con lo de los ataques del "Ping de la muerte" es mas fácil encontrar un punto y coma en un listado de Javascript que un servidor que responda a dicha petición.

Entonces me digo ¿Y si llamo a una URL? Asín, si tengo la seguridad que funciona la dirección a la que llamo (o también probando una colección de URL's) si conecto y obtengo respuesta es que tengo Internet y si no conecto es que estoy desconectado (y me ha salido un bonito pareado).

Para ello hago esta función que invoco desde el Main() de una aplicación de consola.


Sub probarinternet()

Try
Dim url As String = "http://www.nesquicia.com/"
Dim request As WebRequest = WebRequest.Create(url)
' Le bajo el tiempo TimeOut para que vaya más alegre la aplicación
request.Timeout = 1000

Dim response As WebResponse = request.GetResponse

' Hago que espere 3 segundos entre conexiones correctas
System.Threading.Thread.Sleep(3000)
response.Close()

Catch ex As Exception
' Escribo el error y la hora en que ha fallado.
Console.WriteLine(Date.Now & ": " & ex.Message & vbCrLf)
End Try

End While

End Sub

Y el resultado es... que los chapuzas de sistemas nos hacen una desconexión cada pocos segundos!!! Así va de lento esto y falla tanto.

jueves, 22 de noviembre de 2007

Un poquito de SQL

Este es un truquillo que me enseñó hace unos años mi amigo Virgilio para evitar el tostón de andar con condicionales en SQL, en ciertos casos.

Tengo un listado de personas con cuatro parámetros (Nombre, apellido, dirección y teléfono) y quiero buscar por alguno de estos parámetros, por ninguno o por todos. Osea, si meto un nombre que me devuelva todas las personas con ese nombre, y si además le meto la dirección que me devuelva todas las personas con ese nombre y dirección.

¿Qué es lo primero que se le ocurre a un lego en programación SQL como yo? Ale, hacer un condicional y un select por cada uno de los parámetros. Algo como

@nombre
@apellido
@direccion
@telefono

IF @nombre = NULL
BEGIN
Select * from tabla where apellido = @apellido AND dirección = @direccion AND telefono = @telefono
END

Y así por cada uno de los parámetros… y eso sin contar con la tabla auxiliar donde meter los resultados para evitar duplicados, etc. Osea, un porrón de líneas de código.

También he visto hacerlo por medio de código dinámico. Para mi gusto una guarreria que debe dar unos problemas de depuración horrorosos.

@nombre
@apellido
@direccion
@telefono

SET @Select = “select * from table”
SET @Where = ''”
IF NOT @nombre IS NULL SET @Where = @Where + 'nombre=’ + @nombre
IF NOT @apellido IS NULL SET @Where = @Where + 'AND apellido=’ + @apellido
IF NOT @ direccion IS NULL SET @Where = @Where + 'AND direccion =’ + @ direccion
IF NOT @ telefono IS NULL SET @Where = @Where + 'AND telefono =’ + @ telefono

BEGIN
EXEC (@Select + ' WHERE ' + @Where)
END

Y ahora viene la maravilla que me enseño Virgilio, y que ahora comparto en este blog.

@nombre
@apellido
@direccion
@telefono


BEGIN
SELECT * FROM tabla WHERE
(Nombre=@nombre OR @nombre IS NULL)
AND (apellido =@ apellido OR @ apellido IS NULL)
AND (direccion =@ direccion OR @ direccion IS NULL)
AND (telefono =@ telefono OR @ telefono IS NULL)

END

¿A que es complejo de leer?

Pues es muy sencillo. Primero en mi código tengo que asegurarme que el parámetro es uno de dos, o un valor o un NULL. Pero ojo, un NULL de base de datos, osea, un DBNull.value.

¿Qué ocurre cuando, por ejemplo, envío el parámetro @nombre = NULL? El selector de la base de datos lee de forma secuencial desde el principio hasta el final la tabla y va preguntando a cada fila:
-¿Oshes, tu nombre es igual a @nombre? - Y la fila le dice - no, ni parecido-

A lo cual el puntero le vuelve a preguntar a la fila:

¿Oshes el parámetro @nombre es NULL?, a lo cual la fila le dice –pues sí, mira tú-

Y el selector coge la fila y la almacena para ser enviada al finalizar de hacer las mismas preguntas a todas las filas de la tabla.

¿Me entiendess?

Resumen, con estas líneas consigues reducir de forma drástica el código necesario para búsquedas de este estilo.

40 tacos...

Bueno, ya ha llegado el día en que he entrado en una nueva década. Hoy cumplo cuarenta años.

Y he de decir que no me puedo quejar. Tengo una relación estable con la mejor mujer del mundo, la hija más maravillosa que un padre pueda desear, un buen trabajo en donde no me pagan mal, unos buenos amigos (pocos pero los mejores), una buena moto y gozo de SALUD.

Ojalá pueda cumplir otros cuarenta y que todo el que esté leyendo esto lo vea.

miércoles, 21 de noviembre de 2007

Que bueno es tener razón… :)

Hace unos meses, cuando aún trabajaba en Metrovacesa, tuve un debate con un compañero programador (saludines Julio) sobre como almacenar una lista de pares de datos sin tener que tirar de la consabida dataTable en una propiedad… Si no os asustéis, es el tipo de programación que se arrejunta a utilizar “textbox hidden” para jugar al rugbi entre páginas.

Mi compañero me dio una solución, que a mí me parecía un tanto sobredimensionada y poco eficiente y que se trataba de hacer un array. Y que esos objetos fueran una clase con dos parámetros.

Dim personas() As ArrayList

Public Class cliente
Public id As Integer
Public nombre As String
End Class

Public Sub pintaPersonas()
Dim cliente As cliente = New cliente
cliente.id = 1
cliente.nombre = "Juan Carlos "
personas(0) = (cliente)

Response.Write(TryCast(lista(0), cliente).nombre)
End Sub


Y ahora, casi medio año después, y metido en el fregao de la certificación (sigo bendiciendo el día que me gasté la pasta) veo que mi argumento de: seguro que hay alguna manera de hacerlo más sencillo, era totalmente cierto.

Existe un tipo de colección en .NET del tipo IDictionary que nos permite almacenar pares de datos con el formato (clave, valor). Haciendo lo mismo que con el sistema anterior pero de una forma mucho más elegante, compacta y, sobre todo, potente por los métodos implícitos.

Dim lista1 As New Hashtable
lista1.Add(0, "Juan Quijano")


Anda que no hay diferencia en líneas de código ni na’. Además me permite poder sacar un listado de todas las entradas de forma muy sencilla.

For Each personas As DictionaryEntry In lista1
Response.Write(personas.Key & " " & personas.Value & "
")
Next


O invocar a cualquier registro en la colección a través de su indice. Sin que rompa si invoco a un indice que no existe (maldito error por IndexOutOfRange)

Response.Write(lista1(0))

Osea, si que sí había una forma más corrécta y elegante de hacer las cosas… je, je, je.

martes, 20 de noviembre de 2007

Usando Using e IDisposable

Cuando empecé el curso de mi primera certificación Microsoft, que estoy justo por la mitad de temario y tiempo, nuestro tutor nos pidió que investigáramos los métodos para eliminar objetos que ya hemos utilizado de la memoria. El típico Dispose u object = nothing.

Pasaron las semanas y me encontré un día estudiando las diversas formas de pegarte con un SQLDataAdapter y entré a una página de MSDN en donde utilizaban una extraña instrucción que no había visto nunca: Using.

Using connection As New OleDbConnection(connectionString)

Dim command As New OleDbCommand(queryString, connection)
command.CommandTimeout = 20
connection.Open()

Dim reader As OleDbDataReader = command.ExecuteReader()
While reader.Read()
Console.WriteLine(reader(0).ToString())
End While reader.Close()
End Using

Visto el cómo se utilizaba y lo que hacía, fui raudo y veloz a comentárselo a mis tutores los cuales me confirmaron que es una instrucción de .NET 2.0 que nos reduce mucho el código y evita puntos de error por olvidar cerrar una conexión o liberar el adaptador.

Mira en el ejemplo lo que varía el código usando Using y sin usarlo.

Tan contento, voy y defino una clase de conexión a la base de datos, con las llamadas a los procedimientos almacenados y demás zaranjandas, para ser invocado desde la capa de negocio de la aplicación. Pero me llevo la sorpresa que, cuando voy a utilizar Using, me dice que mi clase debe tener implementado el método IDisposable.

En el primer momento me vi recorriendo MSDN, la web del Guille y demás foros buscando a qué se refería, más entonces recordé que en la Certificación hemos dado Interfaces… ¡¡y con eso he amortizado el curso entero!!

Ni corto ni perezoso me voy a mi clase de conexión y le digo:

Implements IDisposable

Ale hooop!!, por arte de Magia (de Visual Studio) se me añaden los parámetros y métodos que necesito para que mi clase soporte Idisposable y que pueda utilizar Using.

Taxativamente te avisa que no lo toques… ;D

Private disposedValue As Boolean = False ' To detect redundant calls

' IDisposable
Protected Overridable Sub Dispose(ByVal disposing As Boolean)
If Not Me.disposedValue Then
If disposing Then
' TODO: free managed resources when explicitly called
End If

' TODO: free shared unmanaged resources
End If
Me.disposedValue = True
End Sub

#Region " IDisposable Support "
This code added by Visual Basic to correctly implement the disposable pattern.
Public Sub Dispose() Implements IDisposable.Dispose
' Do not change this code. Put cleanup code in Dispose(ByVal disposing As Boolean) above.
Dispose(True)
GC.SuppressFinalize(Me)
End Sub
#End Region

Y ahora estoy SEGURO que no voy a intentar abrir una conexión que ya está abierta, ni catorce conectores en memoria… :D

jueves, 15 de noviembre de 2007

Handles y cTypes

Una de las primeras cosas que hice en Visual Studio fue darle lógica a un botón. Es decir, que cuando lo pulse ocurra algo.

Me llamó la atención el montón de “palabros” que pone el .NET para hacer algo así (yo que venía del ASP)

Protected Sub btBoton_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btBoton.Click
End Sub

Hasta que llegué al curso del certificado y aprendí porqué cada cosa aparece en esta sentencia., maravillandome con dos cosas en especial:

1. Le puedo poner el nombre que quiera al método.
2. Le puedo asignar este método a todos los botones que quiera.

Sabiendo esto, comprendí que ya no necesitaba un método para cada botón y que me podía hacer un solo método que me gestionara la lógica de los botones de mi formulario.

Protected Sub haPulsadoUnBoton(ByVal sender As Object, ByVal e As System.EventArgs) Handles bCodigo.Click, bDescripcion.Click

Pero… y siempre hay uno, ¿cómo sé yo que botón ha sido el que ha lanzado el método?
Pues , para eso tengo un peaso tutor (José Manuel Alarcón) y me da una pequeña línea que ya estoy utilizando en proyectos reales y que abre las puertas a tener toda juntita la lógica de los controles.

cType(sender, button).ID

¿A cualo? Y esto que hace?

sencillo. El cType convierte al objeto sender (para los no angloparlantes como yo es algo así como el remitente) al tipo botón. Y entonces puedes recuperar el ID que nos devuelve un string con el nombre del botón.

Si construyo un select case y ya puedo tener un árbol de decisión que me ejecuta código de acuerdo al ID del botón que he pulsado como por ejémplo:

Protected Sub haPulsadoUnBoton(ByVal sender As Object, ByVal e As System.EventArgs) Handles bCodigo.Click, bDescripcion.Click
Select Case CType(sender, button).ID
Case "boton1"
Response.write(“Has pulsado el boton1”)

Case "boton2"
Response.write(“Has pulsado el boton1”)
End Select
End Sub

No te olvides de incluir en el formulario los dos botones: boton1 y boton2.

P.D. Echarle una ojeada a lo que nos muestra el IntelliSense para los métodos de los controles. Te permite hasta capturar eventos en el cliente.

P.D.D. Como os habréis percatado, espero, soy carne de ASP.NET, por eso lo del response.write.

Eha, otro día más...

Historias de un Certificado

Ale, con casi 40 tacos y un montón de años programando en todo tipo de lenguajes y pseudolenguajes, me veo de nuevo con la ilusión de ir a la escuela a ver qué cosas nuevas me enseñan.

Hacía tiempo que le estaba dando vueltas a las famosas certificaciones de Microsoft y había oído opiniones a favor y en contra. En diferentes academias había leido presupuestos totalmente divergentes, y ninguna de ellas me causaba la confianza suficiente como para decidirme dar el paso (además del dinero, que siempre encontraba algo mejor en que gastar).

Y mira tú por dónde (atención publicidad) entré en la página de Guillermo “El Guille” Som y veo que una tal CampusMVP tiene abierta la convocatoria para los cursos de Certificación de Microsoft.

Llamo por teléfono y una amable señorita me explica de forma clara y concisa cuales son los pasos a seguir, empezando por la Certificación 70-536, las pelas que cuesta y cuando empieza el sarao.

Y hete aquí que una vez soltada la pasta, que al final fue menos de lo que pensaba (450€), veo que el curso on-line pinta más que bien y que tengo como tutores del curso, nada más ni nada menos, que a dos bestias pardas como José Manuel Alarcón y al mismísimo Guille.

En resumen, estoy aprendiendo una barbaridad sobre el cómo y el porqué del desarrollo en .NET en general y en VB en particular, con la constante sensación de llevar haciendo el “primo” todos estos años creyéndome el primo de Zumosol de la programación.

Y la moraleja es que voy a seguir certificándome por el mero placer de aprender más sobre mi profesión y mis herramientas de trabajo disfrutando de la sensación de hacer las cosas bien.

Un abrazo a mis tutores y a ver si nos tomamos esas cañitas juntos.

miércoles, 14 de noviembre de 2007

Toc, toc...

Bueno, después de dos intentos por fin consigo introducirme en la blogosfera y en ser uno más de los millones de granos de arena en esta inmensa playa de información.


El objetivo principal es compartir mis experiencias en la programación y desarrollo de proyectos Web, pero también un poco un sitio donde desahogarme y poder soltar tres o cuatro pensamientos que me llenan la cabeza a veces.


Osea, lector, no esperes maravillas. Aquí hay solo un hombre que se escribe así mismo.