Interval and TimeSpan

Posts   
1  /  2
 
    
Otis avatar
Otis
LLBLGen Pro Team
Posts: 39615
Joined: 17-Aug-2003
# Posted on: 24-Aug-2009 10:00:28   

Haaz wrote:

Hi,

I grabbed the query from the inner exception ErrorSql field.

Here is the original one with parameters :


    Query: UPDATE "globaldata"."QueueItem" SET "ElapsedTime"=:ElapsedTime1 WHERE ( "globaldata"."QueueItem"."QueueItemID" = :QueueItemId2)
    Parameter: :ElapsedTime1 : Object. Length: 0. Precision: 0. Scale: 0. Direction: Input. Value: binary lob.
    Parameter: :QueueItemId2 : Int32. Length: 0. Precision: 0. Scale: 0. Direction: Input. Value: 1.

That suggests the timespan value you returned from the typeconverter was not passed properly. I'll see if I can reproduce it with a similar type converter.

Frans Bouma | Lead developer LLBLGen Pro
Haaz
User
Posts: 15
Joined: 19-Aug-2009
# Posted on: 24-Aug-2009 10:15:26   

OK Thank you.

I'm trying to tweak my type converter to see if I can fix this easily

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39615
Joined: 17-Aug-2003
# Posted on: 24-Aug-2009 10:35:38   

I can save and load from the db properly. Using this typeconverter:


[Description("Converter with as core type System.Timespan, for mapping a field with a .NET type Timespan onto an interval database field")]
public class NpgsqlIntervalConverter : TypeConverter
{
    public NpgsqlIntervalConverter()
    {
    }

    public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
    {
        return ((sourceType==typeof(NpgsqlInterval)) || (sourceType==typeof(TimeSpan)));
    }

    public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
    {
        return ((destinationType == typeof(NpgsqlInterval)) || (destinationType == typeof(TimeSpan)));
    }

    public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
    {
        if(value == null)
        {
            return null;
        }
        if(value.GetType() == typeof(NpgsqlInterval))
        {
            return ((NpgsqlInterval)value).Time;
        }
        return value;
    }

    public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType)
    {
        if(value==null)
        {
            throw new ArgumentNullException("value", "Value can't be null");
        }
        // value is always a Timespan
        return new NpgsqlInterval((TimeSpan)value);
    }

    public override object CreateInstance(ITypeDescriptorContext context, System.Collections.IDictionary propertyValues)
    {
        return TimeSpan.Zero;
    }
}

and this testcode:


using(DataAccessAdapter adapter = new DataAccessAdapter())
{
    TestTabEntity t = new TestTabEntity();
    t.IntervalCol = new TimeSpan(2, 4, 0);
    Debug.Assert(adapter.SaveEntity(t, true));

    Debug.Assert(t.Id > 0);

    TestTabEntity toLoad = new TestTabEntity(t.Id);
    Debug.Assert(adapter.FetchEntity(toLoad));

    Console.WriteLine(toLoad.Fields[(int)TestTabFieldIndex.IntervalCol].CurrentValue.GetType().FullName);

    Debug.Assert(t.IntervalCol.Equals(toLoad.IntervalCol));
}

The trace sees the interval as a binary blob, i.e. the DbType property of the parameter is set to 'object', which is ok, the provider knows it's a NpgsqlInterval object.

When I return 'value' instead of a new NpgsqlInterval object (so I return the Timespan) it also works. Could you try the typeconverter above for me please?

Please do realize that the 'Interval' type in postgresql can span several days. Timespan can't. So if you want to store several days of time in the interval typed field, you will get overflow errors. In that case, you might want to consider a startdate/enddate approach.

Frans Bouma | Lead developer LLBLGen Pro
Haaz
User
Posts: 15
Joined: 19-Aug-2009
# Posted on: 24-Aug-2009 11:43:12   

Hi Frans,

I just tested your type converter and get the same error :

{"An exception was caught during the execution of an action query: ERROR: 42601: syntax error at or near \":\". Check InnerException, QueryExecuted and Parameters of this exception to examine the cause of this exception."}

Query :


    Query: UPDATE "globaldata"."QueueItem" SET "ElapsedTime"=:ElapsedTime1 WHERE ( "globaldata"."QueueItem"."QueueItemID" = :QueueItemId2)
    Parameter: :ElapsedTime1 : Object. Length: 0. Precision: 0. Scale: 0. Direction: Input. Value: binary lob.
    Parameter: :QueueItemId2 : Int32. Length: 0. Precision: 0. Scale: 0. Direction: Input. Value: 1.

Real query :

UPDATE "globaldata"."QueueItem" SET "ElapsedTime"=00:18:51::interval WHERE ( "globaldata"."QueueItem"."QueueItemID" = 1::int4)

For some reason, I could not use your type converter in LLBLGen without changing the CanConvertFrom to the following :

return ((sourceType.FullName == "NpgsqlTypes.NpgsqlInterval") || (sourceType.FullName == "System.TimeSpan"));

I was getting an error stating that LLBLGen could not locate the correct version of Npgsql (2.0.0.0 in my case). I will try to upgrade to the latest Npgsql, there might be something that changed in their library.

Haaz
User
Posts: 15
Joined: 19-Aug-2009
# Posted on: 24-Aug-2009 11:57:43   

Hi Again,

I just wanted to report that everything runs smoothly, with both my type converter and yours (except for the modified line listed above) when using Npgsql v2.0.6.0. It seems like they fixed something in between.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39615
Joined: 17-Aug-2003
# Posted on: 24-Aug-2009 14:05:35   

Haaz wrote:

Hi Again,

I just wanted to report that everything runs smoothly, with both my type converter and yours (except for the modified line listed above) when using Npgsql v2.0.6.0. It seems like they fixed something in between.

Yes I was using 2.0.6.0. They had to fix 3 crucial bugs it seems in NpgsqlInterval according to the forums there, so I guess you ran into one of those. simple_smile

Frans Bouma | Lead developer LLBLGen Pro
Haaz
User
Posts: 15
Joined: 19-Aug-2009
# Posted on: 24-Aug-2009 14:09:46   

Thanks a lot for your help, this is much appreciated. Having great tools is one thing, but having them with great support is yet another simple_smile

Strange that I had to replace the CanConvertFrom but this is probably related to Npgsql 1.0 and 2.0 being on my system (as I have a 1.0 in my LLBLgen directory that came with the installer).

Anyway both ways to do the convertFrom are doing the same so this does not really mater.

Thanks again for your reactivity and keep up the good work with this excellent ORM.

Manu

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39615
Joined: 17-Aug-2003
# Posted on: 24-Aug-2009 14:39:31   

Thanks for the kind words, Manu! simple_smile

Frans Bouma | Lead developer LLBLGen Pro
1  /  2