With this post I want to start a series of "Did you know?" regarding programing related topics and db4o features / usage patterns that may not be well known.

As the first one, take a look in the following code:
 

class Address
{
  public Address(string streetName)
  {
     StreetName = streetName;
  }

  public string StreetName { get; set; }

  public override string ToString()
  {
     return "Address: " + StreetName;
  }
}

class Person
{
   public Person(string name, Address address)
   {
       Name = name;
      _address = address;
   }

   public Address Address
   {
      get { return _address; }
      set { _address = value; }
   }

   public string Name { get; set;}

   public override string ToString()
   {
      return "Person: " + Name;
   }
   private Address _address;
}

using (var db = Db4oEmbedded.OpenFile(databaseFileName))
{
   db.Store(new Person("Adriano", new Address("You know where I live")));
   db.Store(new Person("Sulivan", new Address("Monstropolis")));
   db.Store(new Person("Mike", new Address("Who cares?")));
   db.Store(new Address("Foo address"));

   IQuery q =  db.Query();
   q.Constrain(typeof(Person));
   IQuery descendantQuery = q.Descend("_address");
   
   foreach(var result in descendantQuery.Execute())
   {
      Console.WriteLine(result);
   }
}

What do you think will be the result?

Well, it will return all addresses objects that have a Person as a parent, i.e, "foo address" will not be retrieved/shown! 

You can even specify constrains in both queries (getting the addresses for persons with a specific name!).

Note that this does not work for fields with value type semantics (basically any primitive value, enums [in .Net], string, etc.).

Do you have any db4o topic that, in your opinion, is commonly misunderstood and you would like to discuss? Please, let us know :)



Have fun!

Adriano

In this post I presented the following code.

using Db4objects.Db4o;
using Db4objects.Db4o.Linq;
using System.Linq;

class Item
{
public string Name { get; set; }
public Item Father { get; set ; }
}

public class Test
{
 private const string DatabaseFile = "wwwtc1.odb";
 private static void Main()
 {
     Item item1 = new Item { Name = "Adriano" };
     using (var db = Db4oEmbedded.OpenFile(DatabaseFile))
     {
         db.Store(item1);
     }

     using (var db = Db4oEmbedded.OpenFile(DatabaseFile))
     {
         Item item2 = new Item {Name = "Carol",  Father = item1 };
         db.Store(item2);
     }
 }
}

And asked what was wrong with it (and commenter "tehlike" got it :). 


In line 20 we close the database (technically, the using statement will call IDisposable.Dispose() method on the object container which in turn will close it), reopen it at line 22 and finally add a new object (item2) at line 25.  

Take a closer look in the program and you'll see that item2 references item1 which was stored in the database previously. As the documentation states (here and here), db4o uses a reference system to "memorize" which objects are known to be stored in the database (relying on object identity when checking if a given object is already present in this reference system). 

When a database is opened its reference system is empty, so when storing item2 db4o will store item1 again (after all we re-opened the database, so there are no objects in the reference system and both objects are considered as "new", i.e, need to be inserted into the database),  i.e, now we have 2 instances of class Item with the same contents in the database.

What can a developer do to avoid this behavior? Easy, just let the just opened object container know that item1 has already been persisted by retrieving it before referencing it from item2 :) 

using Db4objects.Db4o;
using Db4objects.Db4o.Linq;
using System.Linq;

class Item
{
  public string Name { get; set; }
  public Item Father { get; set ; }
}

public class Test
{
 private const string DatabaseFile = "wwwtc1.odb";
 private static void Main()
 {
     Item item1 = new Item { Name = "Adriano" };
     using (var db = Db4oEmbedded.OpenFile(DatabaseFile))
     {
         db.Store(item1);
     }

     using (var db = Db4oEmbedded.OpenFile(DatabaseFile))
     {
         item1 = (from Person p in db where p.Name == "Adriano").Single();
         Item item2 = new Item {Name = "Carol",  Father = item1 };
         db.Store(item2);
     }
 }
}

Another possible solution (with less performance impact) would be to not close/reopen the database so item1 would be kept in the reference system and db4o would understand that it does not need to store this object again.

using Db4objects.Db4o;
using Db4objects.Db4o.Linq;
using System.Linq;

class Item
{
  public string Name { get; set; }
  public Item Father { get; set ; }
}

public class Test
{
  private const string DatabaseFile = "wwwtc1.odb";
  private static void Main()
  {
     Item item1 = new Item { Name = "Adriano" };
     using (var db = Db4oEmbedded.OpenFile(DatabaseFile))
     {
         db.Store(item1);
         Item item2 = new Item {Name = "Carol",  Father = item1 };
         db.Store(item2);
     }
  }
}


Have fun!

Adriano

Since I joined db4o I'm actively following our forums and trying to help developers to get their questions / issues answered.

Starting with this post I want to present the most recurring topics (don't know exactly how many) in the format of "What's wrong with this code".

But before we start you may be wondering where are the other parts (since this is titled as Part XI, where are parts from I to X). Well, they do exists in the portuguese posts (titled as "O que esta errado com este código (Parte ?)") so I decided to continue with the numbering schema ;)

Ok, for this first one, take a look in the following code:

using Db4objects.Db4o;
using Db4objects.Db4o.Linq;
using System.Linq;

class Item 
{
 public string Name { get; set; }
 public Item Father { get; set ; }
}

public class Test
{
    private const string DatabaseFile = "wwwtc1.odb";
    private static void Main()
    {
        Item item1 = new Item { Name = "Adriano" };
        using (var db = Db4oEmbedded.OpenFile(DatabaseFile))
        {
           db.Store(item1);
        }
  
        using (var db = Db4oEmbedded.OpenFile(DatabaseFile))
        {
          Item item2 = new Item {Name = "Carol",  Father = item1 };
          db.Store(item2);
        }  
    }
}
If you have done some work with db4o you probably will easily spot the problem.

I'll provide the answer in a future post.

Have fun!

Jun 20, 2009

Going to ICOODB

Hi.

Next week I'll attend the second international conference on object databases in Zürich. Woow!

I am sure it will be really amazing moments; I'll have the chance to meet db4o fellows face to face again, to attend to interesting talks, to talk to db4o community members and db4o enthusiasts! Since most db4o team members will meet at Zurich we're taking the chance to discuss db4o directions also. 

Of course, visiting another country (even though being a work trip) and getting in touch with a different culture will be really a great experience. 

My friends knows how much I like chocolates, so I am sure I am going to get some extra weight :)


The not so nice part is that I'll have a 14 hours flight from Brazil to Switzerland and I must admit that I am a bit anxious with the latest flight news (the interesting thing is that I am almost sure I'll have some nice live pair programing session with my good friend Rodrigo while we wait for our flight).


The worst part is to be far from my wife / daughter (I'll miss my daughter's school presentation).


For those that I'll meet at Zurich, see you soon. For everyone else, see you in this blog :)


Best

Adriano

Hi!

Some time ago I started developing a .Net application that requires a control to display hexadecimal values; considering that I could not find a suitable one (and also, that I do suffer for the NIH syndrome) I decided to write one myself.

After some time developing the application I lost interest (since I moved jobs and the main goal of the application was to make my previous job easier) and now it is kind of abandoned but I think that the hexadecimal control may be handy for some developers.

Here is a list of this control's main features:

  • Find
  • Print / Print Preview
  • Ranges: It's possible to specify that some byte ranges should be displayed with a specific color for instance
  • Selection
  • Cut/Past
Since the application is released under an open source license anyone can grab the sources, or, if you are interested I can add you as a developer on source forge!

Best

Adriano


In my last post I was talking about some issues I found while trying to automate the process of launching  a web browser, navigating to a specific page and grabbing some results.

I do have a bunch of stickers with sayings: "Works on My Machine (tm)" but this time I could not even use one of them since even in my machine it refused to work :(. So, the goal of this post is to explain the reasons I got so much pain...

Since an image speak for 1000 words, here it is:

I am sure you already got it. As you can see I am running Vista x64 on my machine and, as explained here and here, when launching IE through Quick Launcher, the 32 bits version is the one that gets launched; by the other hand, when started through COM the bitness of the launcher defines which IE version gets started (32 or 64 bits).
 
In my case (remember, my first approach was to use a JScript script to automate IE) I was trying to start it from Windows console application (cmd.exe) that happens to be a 64 bit application. That's explain why IE insisted to offer me to install Silverlight; on IE 64 bit version I had not installed it (actually, unfortunately, as of today, Silverlight has support for this platform).

The next step was to figure out why my C# application (the one that hosts the WebBrowser control) was failing with the same symptoms. To be sincere, since I had already faced similar issues when using COM components on .Net applications in x64 machines, this one was a lot easier: Again, as explained here, by default VS sets your application to run on whichever processor architecture (regarding to bitness) you throw at it, i.e, it sets the "target platform" to "Any CPU":

That's mean that in a 64 bit machine (like mine) this application will run in 64 bit CLR, hence IE x64 being launched! Peace of cake :). All I had to do was to set this configuration to "x86". Finally my day would be a little less frustrating than I anticipated it to be.

Really fun, don't you agree?

For the next post I am planing to continue on this subject: 32 x 64 bits developer's pitfalls.

Have fun!

Adriano

Yesterday was a frustrating day. By the morning I started to work (pairing with a really smart friend) on an apparently simple task: to automate the process of starting an internet explorer (ie) instance, navigate to a specific page stored on the local machine, wait for some processing to finish (notified by the page) and grab the results. Having some years of experience with Microsoft technologies, mainly developing COM components, and aimed with (lack of) humbleness I started to write a jscript script to drive IE through automation, after all how hard could that that be? Indeed, the first part was really easy:

var browser = new ActiveXObject("InternetExplorer.Application");
browser.Visible = true;
browser.Navigate("http://programing-fun.blogspot.com");
I run the just finished prototype and the browser opened, navigating to the desired page. I was really happy (and thinking how I am smart). So far, so good. But things started to get weird really fast. Even having a good grasp on IE's object model (I don't know it by heart) I failed miserably to retrieve a reference to a page element:
var browser = new ActiveXObject("InternetExplorer.Application");
browser.Visible = true;
browser.Navigate("http://programing-fun.blogspot.com");
while (browser.Busy) {
WScript.Sleep(10);
}
var element = browser.Document.getElementById("some-id");
After some time we decided to give up on using jscript and switched to C#, so I created a Windows Form application to host WebBrower control (hum... someone said IE?) but we kept seeing strange behavior. For instance, the page we were trying to load hosts a Silverlight application but IE insisted that we should install Silverlight; WTF? I do have Silverlight installed !!! Well, at that time I was not felling so smart anymore; and since it was almost lunch time we decided to continue latter. When I got back to work I was determined to get it working so I did what any reasonable developer does in such situations: I decided to do something else :) and I ended up watching a screencast about how to improve the experience for users that don't have Silverlight installed; hum.. interesting. The presenter suggested to disable the Silverlight add-on (instead of uninstalling it). Great! Maybe the add-on was just disabled (due to some stricter security configuration when launching IE through automation). Why I haven't thought about this before? I started my application (C#) as fast as I could and a new browser appeared (in the same way as before), then I went to the add-on configuration dialog and voilà! There was no Silverlight add-on listed (how could I enable/disable it?) So the problem was that, for some reason, IE was not even considering Silverlight add-on to be installed (but that was what IE was trying to say me all the time no?). Then I launched IE manually (clicking on its icon on desktop) and opened the same add-on configuration dialog. This time I could see that Silverlight (and a lot of other add-ons) were installed and enabled.
Well, now I was starting to fell better :). But I still had to understand why I was getting different behaviors depending on how I launched IE. After some head screeching followed by some thinking and some extra searches I do figured out the issue, but that's the subject of the next post :) Have fun! Adriano