Please click this logo to help me get on their beta program:

Xobni outlook add-in for your inbox








31/3/2005

Copernic Desktop Search 1.5 has been released

Filed under: General, Software, Tablet PC — Oliver Sturm @ 5:30 pm - 3 years, 6 months ago

Copernic Desktop Search has had its version 1.5 released. I’ve had a look at it to see if maybe some of my suggestions from my article What I’d like to see in Copernic Desktop Search have made it into the final version. Unfortunately, there’s doesn’t seem to be any information on changes that have been made since the beta version, so it’s easy to miss something. Dear Copernic guys, maybe you could publish some more information on changes you make during development cycles?

Good news

CDS can now index offline mail and news folders for Thunderbird. Not so good news is, it’s incredibly slow… like one article a second, or even less than that (and these are newsgroup postings, very short in average and 99% without attachments). As the Index status window shows, the status jumps back to “email indexing complete” between every two articles, I guess that’s probably not correct anyway. I thought I was going to index some of my mail folders with this feature, but those are usually around 10000 messages each, so maybe that’ll have to wait for now.

An issue I found is that for each of my IMAP accounts, two separate INBOX hierarchies are shown. Obviously there’s only one such hierarchy in reality, no idea where the other comes from. There doesn’t seem to be any difference in the folders underneath the two. Here’s what this looks like:

Bad news

A much worse problem is that the offline folder email indexing doesn’t seem to work at all. I tested this twice, once with an offline newsgroup folder, then with an offline IMAP folder. (BTW, if larger configuration changes are made, it’s always a good idea to restart CDS. More than once it happened to me that after I had removed a folder from the current email indexing configuration, CDS still continued indexing it, until I restarted it.) In both cases, CDS wasn’t able to show me the correct content of indexed entries! I just tried selecting individual entries in the “All Emails” view to see their content in the preview. This didn’t really work at all… I’m sounding cautious because the behaviour was so funny: CDS would always show me content of one email in the list, but it would show that same content regardless of my current selection. I didn’t even get the impression that this content really belonged to one of the emails I actually clicked on. Every once in a while, when I repeatedly changed selection, the content would change, too, only to stay the same again for the next 30 (or so) clicks.

More bad news

None of my other suggestions have been taken up be the developers. Not so nice… especially since I can’t imagine some of them to be that far out, or that difficult to implement, like the suggestion to enable indexing of browser-related information for more than one browser at the same time.

Even more bad news

As Marc Orchant and James Kendrick have been reporting in recent blog articles (this is Marc’s and this is James’s), there are serious issues running CDS on TabletPCs. I have one of those myself, so I’m really interested in this, and Copernic doesn’t seem to show any interest in solving these issues. Maybe it would be useful if more TabletPC users contacted Copernic and told them that this is important to us.

Conclusion

Well, I don’t like it too much. Copernic have managed to introduce a few serious bugs in CDS since the beta and they haven’t taken up much that was suggested at that time. My C# custom extractor for CDS still runs, but they haven’t done anything to extend the shortcomings of the extension API, for example with previewers or the ability to influence the scanning process itself. Obviously, CDS is free software, but it wouldn’t have to be if you ask me. Actually, I have three licensed programs by Copernic and none of them is being as actively developed as CDS is. Maybe Copernic would do good to listen to their users, to better coordinate their development and test cycles and for a product that may still be leading in a very competitive market… but they don’t have too much time to make the right decision here.

29/3/2005

Don’t use exceptions for flow control

Filed under: Programming, .NET — Oliver Sturm @ 5:45 pm - 3 years, 6 months ago

I just read a blog entry titled A word from the “Wise”: Don’t Use Exceptions on Alex Papadimoulis’ weblog. He describes in great length how a so-called MVP had told him that using exceptions was a bad idea and continues to prove in ten points why he doesn’t believe it.

Well, not. The only thing Alex proves is that he didn’t remotely understand what that MVP guy was (probably, I’m only guessing here, of course) talking about. The most important hint is one that Alex misses completely: The MVP said not to use exceptions, but instead use return codes… now, what might that have been about?

The answer is simple, and it doesn’t take an MVP to tell anyone… a simple Google search says enough about this. Exceptions are not a tool for flow control!

What does this mean? Simple, for example: If you are going to divide something by something else, it’s a much better idea to check the divisor for zero than to catch a DivideByZeroException. That’s what the MVP dude meant when he was talking about exceptions killing performance: it’s a simple processor instruction to check a variable for a specific value, it’ll take thousands of additional cycles to throw an exception and catch it, the result is the same.

An exception is meant as an instrument to signal that your application’s flow has been broken. That’s the one most important feature of the exception handling subsystem: it works across all boundaries of application flow. It’s neither designed nor very useful for any situation where the state of the application is known.

Rule of thumb: if you expect that an error may occur in any specific line of code, and you are going to implement alternate handling for that particular case, don’t use an exception. That’s not an unexpected application state and shouldn’t be handled with an exception.

And then, if you’re going to measure executing speed, at least do it properly. Run a profiler and look at the number of method calls that take place in that small test program of yours. And then imagine, how fast would the .net framework be if some guys who work at MS didn’t know when (not) to use exceptions? Who says that your method is only ever going to be called ten times in a row? What’s your excuse why you didn’t write code that’s as fast as it can be? You laughed when someone tried to explain it to you?

Who switches off his/her computer at night?

Filed under: General, Programming, Software — Oliver Sturm @ 8:52 am - 3 years, 6 months ago

Well, I don’t. I never switch off my computer and I never quit the utilities that are running on it all the time. There may be better reasons for this than I have, but these are mine: I use it 14 hours a day anyway, and to boot my 3.4 GHz Athlon 64 system from a cold state into Windows XP, with all the tools running, it takes 19 minutes, that’s no exaggeration.

In this context, there’s something I absolutely hate: most applications, even small ones, have routines these days that run “regularly”. Many do automatic update checking, some do automatic backups, whatever. And guess what those brainy developers do? They run those processes at startup, somehow assuming that a satisfying regularity will come automatically that way. Great. Crap, of course.

Guys, don’t do that! It’s useless! Many people don’t restart your application all the time, so it just doesn’t work! And I’m sure those apps take their share of the 19 minutes boot time, because once they are actually restarted it’s something that happens only every few weeks, so all the update checks/backup/whatever take place at the same time. Who comes up with such an idiotic idea?

26/3/2005

Defining data consistency in an object world

Filed under: Programming, .NET, XPO — Oliver Sturm @ 12:07 pm - 3 years, 6 months ago

Many things change with the decision to work with purely object-oriented data in a specific situation. The outlook seems good: business processes and rules will be much easier to implement, completely typed data will be no problem at all and there’ll be no more structural problems trying to accomodate clumsy handling of records and rows in an otherwise OO application structure. There’ll be an object/relational mapping tool that takes care of all the persistence issues. There’s one thing though that will pose problems much greater than originally anticipated, and it’s easy to overlook large parts of that in the original decision: the wide topic of data integrity in the object world (OW).

I’m going to present some general questions and theories about data integrity in conjunction with OO data objects in this article and I’m planning to write some further articles on the same topic later. Occasionally I may reference the technology I’m personally using at the moment, which is .NET 2, the C# language and XPO.

Data integrity, what about it?

First of all, data integrity comes in two flavours:

  1. The technical side of things is where we are talking about referential integrity on a database level, mapping of field types between databases and programming languages, things like that.
  2. The logical part is part of what’s often referred to as Business Logic. There are definitions for value ranges, maximum counts of assignments between objects, valid states of object fields and much more. Obviously, business logic in its whole may encompass lots of other things, the part that’s relevant here is only where it relates to object data in the objects, as opposed to object data in flow between objects and states.

Many aspects of both data integrity parts are very different in the OW, compared to a “simple” relational database model.

Why is it different?

People have been thinking about these issues for the relational database scenario for a long time. Concepts like referential integrity and unique indexes are very important in this domain. Normalisation provides for database configurations where automated referential integrity can be fully exploited. Databases have features that let the designer restrict values, together with modern database access layers like ADO.NET the complete technical side of data integrity and possibly some of the logical part is covered by these mechanisms.

In the OW, this is where the problems start. Obviously, a good o/r mapping tool should be able to exploit the features of the database layer, but this isn’t sufficient. As soon as a single object is mapped to more than one table (as it should be, when inheritance is used), many of these mechanisms break. For example, it’s impossible to define a multi-value index, unique or not, for values that are not in the same table. Depending on implementation details of the o/r mapper, even unique indexes over fields that are in the same table may present problems, for example if the mapper doesn’t make sure that all necessary fields of an object are filled (correctly!) before the object is first saved to the database.

When working directly with relational databases, the easy way to implement business logic is on the server side. Using triggers on the database level, consistency checks can be implemented, other processes executed just in time and so on. Unfortunately, this has a lot of drawbacks; one of the worst is that there’s no easy way to get useful user feedback in case a check fails. In real-world applications, more often than not business logic implementations will be split, performing some kinds of actions on the database level while leaving other stuff to the client application. For the latter part, it’s difficult to find the right “place” where to implement it, in .NET a typed dataset can provide part of a useful answer.

As long as there’s any server-side consistency checking implemented, there’s always the problem that data which is already loaded on the client, and has been changed there, may not adhere to the same restrictions the server would enforce if the data was to be saved. The programmer has to keep an eye on the exact state of things and see to it that data is saved to the server in all the right places.

There are two aspects to this issue: First, an o/r mapping tool should be allowed to define it’s own database structure with as much freedom as possible. (I know that a lot of people think that this should work the other way round, letting them define a structure and leave the tool to deal with that. Apart from situations where one needs to work with legacy data structures, this is nonsense to me and contorts the purpose of such tools.) Obviously, I’d have to be very careful when writing database layer code that successfully uses the information in the generated layout, and I’d risk breakage every time I update the tool.

Second, from the OW point of view, it seems intolerable to have a number of objects in memory at any given time that may not be in a consistent state. With relational data, this is often a situation that’s simply left to the developer of each distinct algorithm. But when objects are global to the application (or parts of it, at least) and there are intelligent caching and lifecycle management mechanisms in place, as implemented by a useful o/r mapper, one can’t live with the possibility of inconsistent states in in-memory data.

Consequences

So, these are (some of) the specific issues we have to deal with in the OW:

  1. The consistency of in-memory data has much greater importance in the OW. Also, in-memory data is probably a more common thing to have to deal with.
  2. Standard mechanisms on the database layer may be partly useless and there’s no ready-made replacement. Client-side counterparts like the index support in .NET datasets are not immediately available.
  3. While obviously consistency checking systems like those implemented in triggers on a database server can be implemented client-side in an object framework, there’s no fixed point where this can be implemented. Everybody knows what a “before insert” trigger in a database is good for, but where do I put the same code in my OW?

These issues and their solutions will be subjects of future posts. Thanks for reading so far!

23/3/2005

WinForms controls and the red X

Filed under: Programming, .NET — Oliver Sturm @ 7:39 pm - 3 years, 6 months ago

Most people working with WinForms have probably encountered that red X that is drawn over a control at some point and just doesn’t go away as long as the application is running. Originally, I had a look at the source of this some months ago and now, when I saw a relating question again, I thought I might document my findings here.

Note that I did that research with .NET 1 and I haven’t checked for .NET 2 yet, so in the latter case YMMV.

So where does the red X come from? Simple: The System.Windows.Forms.Control has an internal state flag for this that gets set when an exception is thrown in the control’s drawing code. So if you’ve never seen the red X but you want to, just throw a panel on a form and create a Paint event handler like this:

private void panel1_Paint(object sender, System.Windows.Forms.EventArgs e) {
  throw new Exception("Boom");
}

Now, the really interesting thing about the red X is that you can’t easily get rid of it once it’s popped up. The only “official” way is to restart the application. Lucky though that .NET has powerful reflection… that makes it possible to use the following method to reset the state:

void ResetExceptionState(Control control) {
  typeof(Control).InvokeMember("SetState", BindingFlags.NonPublic |
    BindingFlags.InvokeMethod | BindingFlags.Instance, null,
    control, new object[] { 0x400000, false });
}

So you can get that panel in the example above to have another go at drawing itself by going

ResetExceptionState(panel1);
panel1.Invalidate(); // invoke redraw

Of course, if the same exception is still thrown from the paint handler, there won’t be much to see as the state is immediately set back to show the X again.

Generally, of course, you should have a very close look at the reason why there’s an exception thrown in the paint handling code at all. But there are situations where you might want to control the Control’s behaviour in detail and in these cases it’s nice to be able to handle that internal state yourself.

Two additional notes:

  1. You do need certain permissions to get that reflection code to run. If you want to configure your application for exact permission sets, you should use [ReflectionPermission(SecurityAction.Demand, MemberAccess=true)] in front of the ResetExceptionState method.
  2. As I got a request for this at the time, I have a translation of the method in VB.NET, too. I don’t usually use VB, so there may be more elegant ways to do this, but here goes:
Private Sub ResetExceptionState(ByVal control As Control)
  Dim args() As [Object] = {&H400000, False}
  GetType(System.Windows.Forms.Control).InvokeMember("SetState", _
  BindingFlags.NonPublic Or BindingFlags.InvokeMethod Or _
  BindingFlags.Instance, _
  Nothing, control, args)
End Sub

Shooting your screen - a plug for SnagIt

Filed under: General, Software — Oliver Sturm @ 2:59 pm - 3 years, 6 months ago

How do you do screenshots? Is there anybody who doesn’t do them these days? It just occurred to me that I never wrote about my program of choice for this task, SnagIt.

Obviously, some of us may be happy using the built-in Windows functions via the Print Screen key. But there’s a lot more that can be done with proper screen capturing software. I went to evaluate quite a lot of them before deciding to use SnagIt, but most failed at the simple tasks… like working on a multi-head setup, for example.

I’m not saying SnagIt is the best program out there for everybody’s purposes, but you get an awful lot in the package. The capturing system itself is very feature rich and stable. You get a great image editor that has just the right features and there’s another imaging application included that can do advanced stuff with vectorized templates. Every filter that the image editor knows can be used in an automatic configuration, so you don’t have to do anything to get a special border effect on all your shots, for example.

Apart from these things, there’s a lot more in the package that makes SnagIt a useful allround application. There’s a print-to-screenshot printer driver included, and plugins for all the MS Office apps. There’s shell integration and there are browser plugins for Internet Explorer and Firefox. The editor can be used just as well to work on shots that you got from somebody else, and it has all the features you need to make these shots look just as good as if you’d done them yourself.

Is it cheap? No, it’s $39.95. But it’s well worth the money. Go have a look!

Disclaimer: I’m a satisfied customer with no other relations to TechSmith Corporation.

21/3/2005

Side effects of vertical-align in Internet Explorer

Filed under: General, Programming — Oliver Sturm @ 10:54 am - 3 years, 6 months ago

While I was doing some HTML editing yesterday, I stumbled upon an issue in Internet Explorer. I was constructing a table, in one row of which there was supposed to be an image, one pixel high. Looking something like this (showing the border here to make things easier to see):

Text one Text two

To be clear, the image itself is this: (maybe not that easy to see between the table border lines).

I’m quite hopeful that everybody should be able to see the table just the way I was intending it to look, with the cell spanning two columns exactly one pixel in height. Problem was, in the page I was editing yesterday, it didn’t look that way in IE, while it did in Firefox. Instead, it looked something like this (simulated):

Text one Text two

Well, it took me quite a while to find out where this was coming from, and I wasn’t able to find that hint anywhere on the web. That’s why I thought it might be useful for me to publish it here, and also to make me remember it myself if it ever comes up again. So, the reason for this was that somewhere in a voluminous stylesheet system in use with that page, there was this entry:

img {
  border: none;
  vertical-align: middle;
}

Setting the img tag to default to a middle vertical-align shows the problem in IE. Here’s the table once more, this time with a style="vertical-align: middle;" on the img tag. Everything’s as it should be in Firefox, but you should be able to see the problem in IE. For the record, my IE shows version 6.0.2900.2180.xpsp_sp2_rtm.040803-2158 (BTW, do they employ extra staff to create those version numbers?).

Text one Text two

(Ah yes… if you’re just using IE to look at this, do you have any idea why the <pre> box above shows that ugly additional space in the bottom? I never hunted that one down, wasn’t as important as the image thing. Once again, something that doesn’t show in a browser which really understands CSS.)

18/3/2005

Too late

Filed under: General — Oliver Sturm @ 10:34 am - 3 years, 6 months ago
root@ost1 > date +%s
1111142015

Oh well.

checkout -d belly burgers fries cola

Filed under: General — Oliver Sturm @ 10:30 am - 3 years, 6 months ago

Great post by Matthew Baldwin, via KC Lemson’s post.

Like Matthew says: If you don’t get this joke, consider yourself lucky that you’re not as big a nerd as the people who do.

17/3/2005

Balanced matching in .NET regular expressions

Filed under: Programming, .NET — Oliver Sturm @ 5:27 pm - 3 years, 6 months ago

Ryan Byington describes a very interesting feature in the .NET implementation of regular expressions. Definitely worth a read!

16/3/2005

Indexers breaking data binding

Filed under: Programming, .NET — Oliver Sturm @ 8:00 pm - 3 years, 6 months ago

Alright, consider the following situation: There’s a data class with two properties, “Index” and “Content”. There’s a specialised collection typed to contain instances of the data class. Something like this:

public class DataClass {
  public DataClass(string index, string content) {
    this.index = index;
    this.content = content;
  }
	
  string index;
  public string Index { get { return index; } }
	
  string content;
  public string Content { get { return content; } }
}
	
public class MyCollection : List<DataClass> {
}

Of course, if you are using .NET 1, you’ll use a collection derived from CollectionBase instead. As far as I could see, the result would be the same in .NET 1, but I didn’t test it. Maybe someone else could confirm it?

Now, in a little test program, you create some instances of DataClass and stick them in a MyCollection instance. You bind the collection to a DataGrid or a DataGridView, run the app and everything’s fine. Okay.

Now you want to introduce an additional indexer into the collection that will find a specific item by its Index, returning the Content:

public class MyCollection : List<DataClass> {
  public string this[string index] {
    get {
      foreach (DataClass dc in this)
        if (dc.Index == index)
          return dc.Content;
        return null;
    }
  }
}

Run the same test app again and you’ll get a wonderful exception saying “Property accessor ‘Length’ on object ‘DataClass’ threw the following exception:’Object does not match target type.’”

Now what’s happening here? Well, it’s really simple (isn’t it always?). The mechanism that’s used to find out all the properties that are needed to bind a specific collection is quite elaborate. Most of us have probably seen the problem where no properties at all seem to be found because we were binding a collection that didn’t hold any objects at the point where we bound it, just as an example of the complex mechanisms at work here.

In this case, the reason is one I haven’t found documented anywhere: Under specific circumstances, the method GetItemProperties() of the System.Windows.Forms.CurrencyManager is used to fetch a PropertyDescriptorCollection that can be used with a bound collection. For the sake of completeness, this method takes four steps to get hold of a suitable property descriptor collection:

  1. If the bound list is an Array type, the element type of the array is used with the TypeDescriptor to get a property descriptor collection.
  2. If the bound list implements ITypedList, the property descriptors are fetched from there.
  3. The third step is the interesting one, see below.
  4. If the collection contains at least one item, the TypeDescriptor is used to get the property descriptors for the first item in the collection.

Now, the third step is the most interesting one and also the one creating the problems here: Property descriptors are fetched for the collection itself. This list of descriptors is then checked for one that has the name “Item” (which is the name of any indexer properties, even if you normally don’t notice in C#) and a return type that’s not object. If such a descriptor is found, the TypeDescriptor is used to get a list of property descriptors for the return type of that property!

So if you have a look at the sample source code again, it becomes clear what’s happening here. That third step kicks in because the collection has an indexer property that doesn’t return object. The currency manager assumes that the return type of the indexer (did I mention, the method doesn’t even check if there’s more than one indexer) is the same as the type of the items in the collection. Although this may be right more often than not, that’s quite a stupid assumption, if you ask me… even more so if you’re not planning on documenting this behaviour anywhere. Well, in my sample that return type is string, so the property descriptors for string are finally used to access properties of the objects in the collection. The one browseable property that string has is called Length, and that’s exactly what the problem is about in the exception message.

Working around this problem is quite easy: Just implement ITypedList on the collection, with a GetItemProperties implementation like this:

public PropertyDescriptorCollection GetItemProperties(PropertyDescriptor[] listAccessors) {
  return TypeDescriptor.GetProperties(typeof(DataClass),
    new Attribute[] { new BrowsableAttribute(true) });
}

I found this problem in .NET 2, beta 1, and I checked the code of .NET 1.1, too. I haven’t actually tried the sample in .NET 1, though.

15/3/2005

Using .NET 1 nullable types with data binding

Filed under: Programming, .NET, XPO — Oliver Sturm @ 5:28 pm - 3 years, 7 months ago

In this post I showed how nullable types can be simulated in .NET 1, especially for use with XPO. Prompted by Miha Markič, I had a look at the possibility of data binding with those simulated nullable types.

I found that while the implementation I had suggested could be used without problems in a read-only situation, it obviously didn’t contain any logic that would enable editing the types via data-bound controls. Nevertheless, this is easy to do by creating a custom TypeConverter. Like this:

public class NullableInt32TypeConverter : TypeConverter {
  public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) {
    if (sourceType == typeof(string))
      return true;
    return base.CanConvertFrom(context, sourceType);
  }
	
  public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) {
    if (value is string) {
      try {
        int intVal = Convert.ToInt32(value);
        return new NullableInt32(intVal);
      }
      catch (FormatException) {
        return new NullableInt32( );
      }
    }
	
    return base.ConvertFrom(context, culture, value);
  }
}

To activate this type converter for the NullableInt32, you have to decorate the NullableInt32 class with an attribute:

[TypeConverter(typeof(NullableInt32TypeConverter))]
public class NullableInt32 : Nullable {
  public NullableInt32( ) : base(false) { }
  ...

Now you can bind a collection of objects, which contain properties of the type NullableInt32, to a grid and edit the value for the NullableInt32 property. Just enter an invalid or empty string to set the value to null.

Update: Miha pointed me to this obviously more complete implementation of nullable types for .NET 1. I haven’t had a close look at them because my platform is .NET 2 anyway, so I can’t say anything about the implementation, but obviously the main purpose of this post was to show a way of implementing this kind of thing with XPO. I guess that information in usable with the sourceforge implementation of nullable types just the same.

Nullable types in XPO without .NET 2

Filed under: Programming, .NET, XPO — Oliver Sturm @ 1:45 pm - 3 years, 7 months ago

In a previous article, I showed how nullable types, as implemented in version 2 of the .NET framework, can be persisted using XPO. But what if .NET 2.0 is not yet an option? .NET 1.1 doesn’t have support for nullable types and there’s no such feature in XPO, either.

If somebody comes from the database world, it’s certainly understandable that types that can also be null are something he’s accustomed to. On the other hand, XPO is about persisting objects, and in that world, no ordinary value types have ever been able to have the value null. Anyhow, I do think it’s a nice feature to be able to set ints to null, certainly so when persistence to databases is considered.

So, I’ve created a nullable type together with, once again, a value converter, that allows to use nullable value types in .NET 1.1. Here’s the code for a base class and the NullableInt32:

public abstract class Nullable {
  public Nullable(bool hasValue) {
    this.hasValue = hasValue;
  }
	
  private bool hasValue;
  public bool HasValue {
    get { return hasValue; }
    set { hasValue = value; }
  }
	
  public override string ToString( ) {
    return hasValue ? "" : "(null)";
  }
}
	
public class NullableInt32 : Nullable {
  public NullableInt32( ) : base(false) { }
	
  public NullableInt32(Int32 value) : base(true) {
    this.value = value;
  }
	
  private Int32 value;
  public Int32 Value {
    get { return value;	}
    set {
      this.value = value;
      HasValue = true;
    }
  }
	
  public override string ToString( ) {
    return HasValue ? Value.ToString( ) : base.ToString( );
  }
}

When writing these classes, I made the design decision not to implement the object’s value in the base class. Of course, each derived class needs more code because of that, but I avoid a lot of boxing/unboxing (David Cumps has some useful info on that), which might be worthwhile in this context.

The other decision I made was to use a class as opposed to a struct. Using a struct would be a good idea because we wouldn’t need to add a line to the constructor of the data object to get the object initialised. But then we’d have to implement all the functionality in every single nullable type, because there’s no such thing as an “abstract base struct”. By the way, the .NET 2.0 nullable types are implemented using structs, but that’s only made possible by the .NET 2 support for Generics. Something to add to my recent article, I guess :-)

Now we need a value converter to properly store this type into a single field in the database:

public class NullableInt32ValueConverter : ValueConverter {
  public override Type StorageType {
    get { return typeof(Int32);	}
  }
	
  public override object ConvertToStorageType(object value) {
    NullableInt32 val = value as NullableInt32;
    return val.HasValue ? (object) val.Value : null;
  }
	
  public override object ConvertFromStorageType(object value) {
    NullableInt32 result = new NullableInt32( );
    if (value != null)
      result.Value = (Int32) value;
    return result;
  }
}

A data class that uses this type might look like this:

public class DataClass : XPObject {
  public DataClass( ) {
    intVal = new NullableInt32( );
  }
	
  NullableInt32 intVal;
  [ValueConverter(typeof(NullableInt32ValueConverter))]
  public NullableInt32 IntVal {
    get { return intVal; }
    set { intVal = value; }
  }
}

When this data class is persisted, it will use a single database field that’s set to null if the nullable int field doesn’t hold a value.

Of course, this implementation isn’t as elegant as that in .NET 2.0, which makes use of the advantages of Generics and native nullable types. But it’s certainly usable if you tuck away the different NullableXXX classes (created like the one above) and the value converters in a helper assembly. It’s also possible to register a value converter for a specific type globally, so you don’t have to decorate each property with the ValueConverterAttribute. In that case, just make sure to call the registration method before you do any persisting or loading on the XPO data.

Session.DefaultSession.Dictionary.RegisterValueConverter(
  new NullableInt32ValueConverter(), typeof(NullableInt32));

Update: Miha pointed me to this obviously more complete implementation of nullable types for .NET 1. I haven’t had a close look at them because my platform is .NET 2 anyway, so I can’t say anything about the implementation, but obviously the main purpose of this post was to show a way of implementing this kind of thing with XPO. I guess that information in usable with the sourceforge implementation of nullable types just the same.

11/3/2005

SkypeIn beta launched

Filed under: General, Software — Oliver Sturm @ 10:18 am - 3 years, 7 months ago

As of today, Skype have launched a beta for their new SkypeIn service. Currently it’s possible to get numbers in four regions (France, Hong Kong/China, United Kingdom and United States), regardless of where you yourself live, that allow people to dial in to your Skype using “normal” telephone systems. For a year, the subscription costs 30€, 10€ for 3 months. A subscription for the Skype VoiceMail system, that’s also been in beta test for a while now, is included in that price.

To use the new features, you’ll need a newly released beta version of the Skype Client.

9/3/2005

Storing OneNote files on a network drive

Filed under: General, Software, Tablet PC — Oliver Sturm @ 3:04 pm - 3 years, 7 months ago

A OneNote notebook is comprised of separate files, which may be stored in different locations. Sure, if you first create a new “Section” in OneNote itself, the application will create the new file in the default path (which can be customised via Tools/Options/Open and Save). But you can easily move that file elsewhere once it’s been created. Just create a normal Windows link to the file in your notebook folder and OneNote will show the tab with a small symbol on it, so you know that file is not physically part of your default notebook.

This feature has many uses: I use it to link project-oriented OneNote files, that are stored in a directory managed by source code version control, into my main notebook, for example. I also have some files that are stored on a network drive, and that’s where I recently found a problem: While searching my notebook for a string I knew had to be there somewhere, I found that OneNote doesn’t include network-stored files in its search by default. They call that feature “performance enhancement” :-) Well, I found the place where I could switch an option and now things work fine. Can’t help but wonder though, with shared sessions working as well as they do, even over WAN connections, does searching a file on a network drive (which will be on a fast connection, more often than not) really create the kind of load that needs to be optimised?

Next Page »

Powered by WordPress
© Copyright 2005-2008 Oliver Sturm