2012/02/17

scalaIDE + sbt + spec

Entorno de desarrollo con ScalaIDE (Eclipse), sbt y spec.

a) Eclipse helios 3.6.2
b) ScalaIDE (scala 2.9.1)
c) Instalar sbt (0.11)
d) Instalar  sbteclipse

Aunque ScalaIDE utiliza internamente sbt, es necesario instalar una versión externa y un plugin  (sbteclipse) para crear y actualizar el proyecto de eclipse, desde sbt.

Crear MiProyecto/build.sbt (Son relevantes las lineas vacías)
name := "org.acme.miproyecto"

version := "1.0"

scalaVersion := "2.9.1"

libraryDependencies ++= Seq(
    "org.specs2" %% "specs2" % "1.8" % "test",
    "junit" % "junit" % "4.8.1" % "test"
)

Convertir el proyecto a eclipse (crea la estructura de directorios)
 >sbt eclipse

 Importarlo desde eclipse (File -> Import -> General -> Existing projects into Workspace)

Workflow, para añadir una libreria, (jUnit).

1) Cambiar build.sbt

libraryDependencies ++= Seq(
    "org.specs2" %% "specs2" % "1.8" % "test",
    "junit" % "junit" % "4.8.1" % "test"
)

2) En la consola de sbt. >reload  (Para recargar la configuración)
3)  sbt> eclipse
4) En eclipse PackageExplorer -> MiProllecto-> (Boton derecho) Refresh

2011/04/05

EF integration testing, recreate database --> kill All users

Before recreate SQL server database, with no risk of "The database XXX is in use", you must close all open connections.

One option is close pooled connections, but maybe others programs are using database or some connections still are opened because of wrong dispose.

The always work approach is request database to kill all current users, and then obtain exclusive access to run schema update, and later put database in multiuser mode.

Here is the utility methods in base test class:

protected void ChangeDatabaseToMultiUserMode(IDbConnection connection)
{
   try
   {
     connection.Open();
     var cmd = connection.CreateCommand();
     cmd.CommandText = "ALTER DATABASE [" + connection.Database + "] SET MULTI_USER WITH NO_WAIT";
     cmd.ExecuteNonQuery();
   }
   finally
   {
      connection.Close();
   }
}

protected void ChangeDatabaseToSingleUserMode(IDbConnection connection)
{
   try
   {
     connection.Open();
     var cmd = connection.CreateCommand();
     cmd.CommandText = "ALTER DATABASE[" + connection.Database + "] SET SINGLE_USER WITH NO_WAIT";
     cmd.ExecuteNonQuery();
   }
   finally
   {
      connection.Close();
   }
}

protected void KillOpenDatabaseConnections(string dataSource, string databaseName)
{
   SqlConnectionStringBuilder connStrBuilder = new SqlConnectionStringBuilder();
   connStrBuilder.DataSource = dataSource;
   connStrBuilder.IntegratedSecurity = true;

   using (SqlConnection connection = new SqlConnection(connStrBuilder.ConnectionString))
   {
      connection.Open();

      foreach (int processId in GetCurrentConnectedProcessesIDs(connection, databaseName))
      {
         try
         {
            using (SqlCommand killCommand = new SqlCommand("KILL " + processId, connection))
            {
               killCommand.ExecuteNonQuery();
            }
         }
         catch (Exception ex)
         {
            Console.WriteLine("Error killing sql process " + processId 
                            + " reason: (" + ex.GetType().Name + ") " + ex.Message);
         }
      }
   }
}

private List<int> GetCurrentConnectedProcessesIDs(SqlConnection connection, string databaseName)
{
   List<int> resultado = new List<int>();
   string sql = "SELECT spid as Process_ID FROM  MASTER..SysProcesses WHERE DBId = DB_ID('" 
              + databaseName + "') AND SPId <> @@SPId";
   using (SqlDataReader dr = new SqlCommand(sql, connection).ExecuteReader())
   {
      while (dr.Read())
      {
         int processID = int.Parse(dr["Process_ID"].ToString());
         resultado.Add(processID);
      }
   }
   return resultado;
}

And example of usage:

var config = ConfigurationManager.ConnectionStrings["DATABASE_NAME"];
var connection = DbProviderFactories.GetFactory(config.ProviderName).CreateConnection();
connection.ConnectionString = config.ConnectionString;

KillOpenDatabaseConnections(connection.DataSource, connection.Database);

using (var context= new MyDbContext(connection))
{
   ChangeDatabaseToSingleUserMode(connection);
   try
   {
      new DropCreateDatabaseAlways<MyDbContext>().InitializeDatabase(context);
      new DefaultInitializer().InitializeDatabase(context);
      new TestInitializer().InitializeDatabase(context);
   }
   finally 
   {
      ChangeDatabaseToMultiUserMode(connection);
   } 
}

2011/02/24

Tractis integración con asp.net

Estos días, Julian me comento un "reto", realizar un pequeño ejemplo de integración en asp.net con el servicio de identificación de usuarios con certificado digital de Tractis.

Para el que no lo conozca recomiendo dedicar cinco minutos en entrar en la web de Tractis y probar una cuenta gratuita.
(Por fin alguien ha hecho que usar mi Dni-e sea algo simple, sencillo y rápido).



Como buen pisa-teclas que se precie, no me pude resistir a complicar un poco el ejemplo y probar algunas cosas: Los providers sql de asp.net para membership (gestión de usuarios) y de profiles (información adjunta a un usuario).

No me ha convencido mucho el tema de los providers para sql estándar de .net, al final para proyectos reales toca implementar providers propios para membership y pensar dos veces si utilizar profiles, por no comentar que no soportan SQL server CE.

Podéis probar la demo en:
http://extranet.solnatec.com/tractis/

Y descargar el código fuente en https://github.com/dmarzo/Tractis_aspnet_demo

2011/01/24

cocoworking

El anterior jueves asistí a una charla de NASF en un nuevo lugar de coworking en Pamplona cocoworking (primero y único), por resumir, conocí a Iñaki me explico la idea el funcionamiento y no dude mucho, los próximos meses, voy a desarrollar un proyecto, geckoide (en breve cuento algo más) y mudarme a coco, seguro que es una buena idea, hay que romper la rutina!.

El caso es que ya estoy instalado, en menos de lo que cuesta escribir estas lineas, dejo foto para la posteridad:


Me he propuesto venir a trabajar en bici desde Barañain a San Pedro, hay un bonito paseo por el Arga, ayer desempolve la bici después de años, la cadena duro 2 minutos antes de partirse, fácil de arreglar, más costara vencer la inercia de venir en coche, se aparca a la primera.




Para no olvidar ningún nombre, saludar a la gente que he conocido: Oscar 3D, la gente de boutade Patxi y Ruperto , Mikel cuando le pille y Marta la otra jefa y creadora de coco(el logo).

2011/01/17

EF save datetimes in UTC to data base

When you work with various timezones, a good approach to work with dates its store in UTC in database because of databases lack of support for timezones, NET side have tools to work with (DateTime.UtcNow, DateTime.ToLocalTime, TimeZoneInfo) so comfortable, but you need to convert to UTC when you store to database.

One transparent solution is tuning ObjectContext:



First we need to convert all DateTimes to UTC previous save in database:



DateTime class, has a property Kind of type DateTimeKind enumeration with values Unspecified, Utc, Local, our enemy its Unspecified, if you save a entity with a property with DateTime.Kind Unespecified you get the ArgumentException in runtime (sorry no compiler check).
Be aware when you parse DateTime its Kind by default its Unspecified.

And when load from database set de Kind to UTC for all DateTimes:



Disclaimer: This is my first attempt to write something meaningful in Shakespeare language.