ArtinSoft's Blogs

Software Migration Experts
Welcome to ArtinSoft's Blogs Sign in | Join | Help
in Search

Mauricio Rojas Blog

June 2008 - Posts

  • Migrating RDS CreateRecordSet in .NET

    This is way a discused with a friend for migrating a VB6 RDS CreateRecordset

     

    Private Function Foo(rs As ADOR.Recordset) As Boolean
        On Error GoTo Failed
        Dim ColumnInfo(0 To 1), c0(0 To 3), c1(0 To 3)
        Dim auxVar As RDS.DataControl
        Set auxVar = New RDS.DataControl
     
        ColInfo(0) = Array("Value", CInt(201), CInt(1024), True)
        ColInfo(1) = Array("Name", CInt(129), CInt(255), True)
       
        Set rs = auxVar.CreateRecordSet(ColumnInfo)
        Foo = True
        Exit Function
    Failed:
        Foo = False
        Exit Function
        
    End Function

     

    According to MSDN the CreateRecordset function takes a Varriant array with definitions for the columns. This definitions are made up of four parts

     
    Attribute Description
    Name Name of the column header.
    Type Integer of the data type.
    Size Integer of the width in characters, regardless of data type.
    Nullability Boolean value.
    Scale (Optional) This optional attribute defines the scale for numeric fields. If this value is not specified, numeric values will be truncated to a scale of three. Precision is not affected, but the number of digits following the decimal point will be truncated to three.
     

    So if we are going to migrate to System.Data.DataColumn we will used a type translation like the following (for now I’m just putting some simple cases)

     
    Length Constant Number DataColumn Type
    Fixed adTinyInt 16 typeof(byte)
    Fixed adSmallInt 2 typeof(short)
    Fixed adInteger 3 typeof(int)
    Fixed adBigInt 20  
    Fixed adUnsignedTinyInt 17  
    Fixed adUnsignedSmallInt 18  
    Fixed adUnsignedInt 19  
    Fixed adUnsignedBigInt 21  
    Fixed adSingle 4  
    Fixed adDouble 5  
    Fixed adCurrency 6  
    Fixed adDecimal 14  
    Fixed adNumeric 131  
    Fixed adBoolean 11  
    Fixed adError 10  
    Fixed adGuid 72 typeof(System.Guid)
    Fixed adDate 7 Typeof(System.DateTime)
    Fixed adDBDate 133  
    Fixed adDBTime 134  
    Fixed adDBTimestamp 135  
    Variable adBSTR 8  
    Variable adChar 129 typeof(string)
    Variable adVarChar 200 typeof(string)
    Variable adLongVarChar 201 typeof(string)
    Variable adWChar 130  
    Variable adVarWChar 202  
    Variable adLongVarWChar 203  
    Variable adBinary 128  
    Variable adVarBinary 204  
    Variable adLongVarBinary 205  
    So the final code can be something like this: private bool Foo(DataSet rs)

    {

    try

    {

    DataColumn dtCol1 = new DataColumn("Value",typeof(string));
    dtCol1.AllowDBNull = true;
    dtCol1.MaxLength = 1024;

    DataColumn dtCol2 = new DataColumn("Name",typeof(string));

    dtCol2.AllowDBNull = true;
    dtCol2.MaxLength = 255;
    DataTable dt = rs.Tables.Add();

    dt.Columns.Add(dtCol1);

    dt.Columns.Add(dtCol2);

    return true;

    }

    catch

    {

    return false;

    }

    }

     

    NOTES:

    My friend Esteban also told my that I can use C# 3 syntax and write something even cooler like:

    DataColumn dtCol1 = new DataColumn()

    {

    ColumnName = "Value",

    DataType = typeof (string),

    AllowDBNull = true,

    MaxLength = 1024

    };

  • Log4NET for C++

    Recently my friend Yoel had just a wonderful idea. We have an old Win32 C++ application, and we wanted to add a serious logging infraestructure so we can provide better support in case the application crashes.

    So Yoel came with the idea of using an existing framework for logging: LOG4NET

    The only problem was, how can we integrate these two together. One way was problably exporting a .NET object as COM. But Yoel had a better idea.

    Create a C++ Managed application that will comunicate with the LOG4NET assemblies, and export functions so the native applications can use that. How great is that.

    Well he finally made it, and this is the code of how he did it.

    First he created a C++ CLR Empty project and set its output type to Library. In the references we add a refrence to the Log4Net Library. We add a .cpp code file and we call it Bridge.cpp. Here is the code for it:

    #include <atlstr.h>

    using namespace System;

    /// <summary>

    /// Example of how to simply configure and use log4net

    ///
    </summary>

    ref class LoggingExample
    {
    private:
    // Create a logger for use in this class
    static log4net::ILog^ log = log4net::LogManager::GetLogger("LoggingExample");static LoggingExample()
    {
        log4net::Config::BasicConfigurator::Configure();
    }

    public:static void ReportMessageWarning(char* msg)
    {
    String^ data = gcnew String(msg);
    log->Warn(data);
    }

    static void ReportMessageError(char* msg)
    {
    String^ data = gcnew String(msg);
    log->Error(data);
    }

    static void ReportMessageInfo(char* msg)
    {
    String^ data = gcnew String(msg);
    log->Info(data);
    }
    static void ReportMessageDebug(char* msg)
    {
    String^ data = gcnew String(msg);
    log->Debug(data);
    }

    };

    extern "C"
    {

    _declspec(dllexport) void ReportMessageWarning(char* msg)
     {
    LoggingExample::ReportMessageWarning(msg);
    }

    _declspec(dllexport) void ReportMessageError(char* msg)
    {
    LoggingExample::ReportMessageError(msg);
    }

    _declspec(dllexport) void ReportMessageInfo(char* msg)
    {
    LoggingExample::ReportMessageInfo(msg);
    }

    _declspec(dllexport) void ReportMessageDebug(char* msg)
    {
    LoggingExample::ReportMessageDebug(msg);
    }

    }

    Ok. That's all. Now we have a managed C++ DLL that exposes some functions as an standard C++ DLL and we can use it with native win32 applications.

    Let's do a test.

    Lets create a Win32 Console application. And add this code:

    // Log4NetForC++.cpp : Defines the entry point for the console application.
    //
    #include "stdafx.h"
    #include <atlstr.h>
    extern "C"
    {

    _declspec(dllimport) void ReportMessageWarning(char* msg);

    _declspec(dllimport) void ReportMessageError(char* msg);_declspec(dllimport) void ReportMessageInfo(char* msg); _declspec(dllimport) void ReportMessageDebug(char* msg);

    }

    int _tmain(int argc, _TCHAR* argv[])
    {
    ReportMessageWarning(
    "hello for Log4NET");
    ReportMessageError(
    "hello for Log4NET");
    ReportMessageInfo("hello for Log4NET");
    ReportMessageDebug(
    "hello for Log4NET");
    return 0;
    }

    Ok. Now we just test it and we get something like:

    Output

     Cool ins't it :)

  • Oh my god I screwed up my VS Menu

    Ok Ok. I must admitted I have a weird taste to configure my gui. But recently I took it to a the extreme as I (don't know how) delete my File menu.

    I managed to get around this thing for a few weeks but finally I fed up. So this gentleman gave me a solution (reset my settings) http://weblogs.asp.net/hosamkamel/archive/2007/10/03/reset-visual-studio-2005-settings.aspx

     

  • Dataset save columns as Attributes

    This code is so handy that I'm posting it just to remember. I preffer to serialize my datasets as attributes instead of elements. And its just a matter of using a setting. See: 

    Dim cnPubs As New SqlConnection("Data Source=<servername>;user id=<username>;" & _
    "password=<password>;Initial Catalog=Pubs;")
    Dim daAuthors As New SqlDataAdapter("Select * from Authors", cnPubs)

    Dim ds As New DataSet()
    cnPubs.Open()
    daAuthors.Fill(ds, "Authors")

    Dim dc As DataColumn
    For Each dc In ds.Tables("Authors").Columns
    dc.ColumnMapping = MappingType.Attribute
    Next

    ds.WriteXml("c:\Authors.xml")

    Console.WriteLine("Completed writing XML file, using a DataSet")
    Console.Read()
  • Visual Studio and the nasty No files found

    The find in files options of the IDE is part of my daily bread tasks. I use it all day long to get to the darkest corners of my code and kill some horrible bugs.

    But from time to time it happens that the find in files functionality stops working. It just starts as always but shows and anoying "No files found..." and i really irritated me because the files where there!!!! !@#$!@#$!@#$

    Well finally a fix for this annoyance is (seriously is not a joke, don't question the dark forces):

    1.  Spin your chair 3 times for Visual Studio 2003 and 4 times for Visual Studio 2005

    2. In Visual Studio 2003 press CTRL SCROLL-LOCK and in Visual Studion 2005 press CTRL and BREAK.

    3. Dont laugh, this is serious! It really works.

     

Powered by Community Server (Non-Commercial Edition), by Telligent Systems