Falling in love with a ghost :D

After a long time that some friends told me about boo language, finally yesterday I downloaded the trunk and began to familiarize with the language. The first thing that surprised me is the ability to break into debugger with simple instruction like these

import System.Diagnostics

Debug.Fail(“”)

And your favorite debugger will show up with full support for intellisense, step and so on, I’m very pleased with this.

Alk.

An helper class to access databases with ado.

A while ago I read an exceptional post by Ayende, I found it very interesting, and I decided to use his technique with some projects, but I choose to do a little modification to make the code works with every type of database, not only with SqlServer. Here is my version. All real code is made by ayende, I simply do some changes to make it database agnostic.

public static void Execute(VoidFunc<DbCommand, DbProviderFactory> functionToExecute) {
   
DbProviderFactory factory = DbProviderFactories.GetFactory(
      MainConnectionString.ProviderName);
   
using (DbConnection connection = factory.CreateConnection()) {
      connection.ConnectionString = MainConnectionString.ConnectionString;
      connection.Open();
      
DbTransaction tx = connection.BeginTransaction();
      
try {
         
using (DbCommand command = factory.CreateCommand()) {
            command.Connection = connection;
            command.Transaction = tx;
            functionToExecute(command, factory);
         }
         tx.Commit();
      }
      
catch {
         tx.Rollback();
         
throw;
      }
      
finally {
         tx.Dispose();
      }
   }
}

The modification from the original ayende’s code is the following: instead to directly create a SqlConnection I use DbProviderFactories to create a DbProviderFactory, with this object I can create connection and parameter based on the provider name specified in the app config. The connectionstring is taken from a property MainConnectionString that simply use ConfigurationManager to get the connection from the app.config, this property returns a ConnectionStringSettings object that not only stores the effective connection string, but contains also some other properties, such as ProviderName, used to specify the provider. The rest of the code is the same of exceptional Ayende’s example. The delegate I use to execute the query accepts both a DbCommand and a DbProviderFactory that must be used to create parameter for the command. I also inserted another helper function that adds a parameter to the command choosing the right name at runtime based on the provider type (this is necessary because for Oracle parameter names are to be prefixed with :, sql server use @, etc…).

private static Dictionary<Type, String> mParametersFormat = new Dictionary<Type, String>();
 
private static String GetParameterFormat(DbCommand command) {
   
if (!mParametersFormat.ContainsKey(command.GetType())) {
      mParametersFormat.Add(
         command.GetType(),
         command.Connection.GetSchema(
“DataSourceInformation”)
            .Rows[0][
“ParameterMarkerFormat”].ToString());
   }
   
return mParametersFormat[command.GetType()];
}

public
 static void AddParameterToCommand(
   
DbCommand command,
   
DbProviderFactory factory,
   System.Data.
DbType type,
   
String name,
   
object value) {
 
   
DbParameter param = factory.CreateParameter();
   param.DbType = type;
   param.ParameterName = 
String.Format(GetParameterFormat(command), name);
   param.Value = value;
   command.Parameters.Add(param);
}

As you can see I store the format of the parameter in a dictionary indexed by command type. For each different type of commands (SqlCommand, OleDbCommand) I store the ParameterMarkerFormat string that is retrieved with DbConnection.GetSchema() function. This caching could be avoided if we are sure to use the same db in every part of the application (an assumption that is easily true since it is very strange to create an application that stores some data in a sql server and some other data in a different engine, for example Oracle). The ParameterMarkerFormat is a sting that can be used with String.Format to create the right parameter name for the current provider, for example with sql server is “{0}”, while for an access database is “?”, because access only supports positional parameters. Here is an example that use the class to find all customers living in London from the NorthWind database.

Int32 CustomerCount = Nablasoft.Helpers.DataAccess.Execute<Int32>(
   
delegate(DbCommand command, DbProviderFactory factory) {
      command.CommandType = System.Data.
CommandType.Text;
      command.CommandText = 
“SELECT COUNT(*) FROM Customers WHERE City = @city”;
      Nablasoft.Helpers.
DataAccess.AddParameterToCommand(
         command, factory, System.Data.
DbType.String, “city”, “London”); 
      
return (Int32)command.ExecuteScalar();
   });

The connection in the app.config is the following. As you can see the query text use a parameter name prefixed

<connectionStrings>
   <add 
         name=MainDatabase 
         connectionString=Database=Northwind;Server=localhost\SQL2000;User Id=sa;Password=ottaedro_2006@ 
         providerName=System.Data.SqlClient/>
 </connectionStrings>

Now the helper is database independent. I want to thank Ayende for it’s great example, his code is really amazing.

Alk.

Today is not a good day :(

Today is not a good day for a couple of reasons, but now my visual studio instance begins to behave in a strange manner, when I digit ALT+126 to make tilde character in a code windows, a strange chars appears instead of tilde, and the font of the visual studio changes, here how it looks like on my monitor

In every other window ALT+126 works as expected (~), mah……………

Alk.

Windows vista and the nostalgic users of command line :D

I needed to copy the windows sdk file (1.2 Gigabytes) from the desktop pc to my laptop, via Ethernet 100 mbps. I begin navigating to the network folder and try to right click the file to select copy. The result is that my laptop get hung….after some while I realized that my antivirus is trying to scan the network file to see if the file is virus free…I immediately terminate the antivirus, and change the option not to scan network files. Then I try to copy the file again, this time I was able to right click and copy the file, I went to destination folder and then do right click, then paste….a message box appears and the file starts to transfer……but my pc is still hung, after 2 minutes the progress bar is about at 15%, so I manually disconnected network cable, the operation was aborted and I decided to open a dos prompt box an type

copy “\\athlon\Download old H\developer\WinFx\OfficialRelease\6*.*”

after 2 minutes the file was on my laptop, but then I decided to move into another folder of the same partition, again I tried to do this through the windows shell, again a progress bar appears telling me something like “calculating time needed to perform the operation”……WHAT???? I was trying to move a file between folder in the same partition…again I stopped the operation, goes again in dos prompt and typed

move 6.0.6000.0.0.WindowsSDK_Vista_rtm.DVD.Rel.img f:\download\WindowsSDK\

The file was moved instantaneously. This poses a question…why these simple operations are really overkill when managed by windows vista shell and are extremely efficient when performed from a dos shell? Whell….I must admit that I’m a nostalgic command shell user J

Alk.