Dec 29, 2010

What's wrong with this code (Part XII)

In the last post in this series ("what's wrong with this code") we discussed how db4o's reference system remembers which objects have been stored / retrieved.

In this post I'll show you another piece of code that doesn't always work as the developer expects:

class User
{
   public string Name;
   public User Manager;
   public IList Addresses;

   public User(string name, User manager)
   {
      Name = name;
      Manager = manager;
   }
}

class Address
{
   public string Street;

   public Address(string street)
   {
      Street = street;
   }
}  


using (var db = Db4oEmbedded.OpenFile(databaseFileName))
{
   List<Address> addrs = new List();
   addrs.Add(new Address("Street1"));
   addrs.Add(new Address("Street2"));
   User fooManager = new User("Foo") { Addresses = addrs };

   User fooBarManager = new User("FooBar", fooManager);
   User barManager = new User("John Doe",  fooBarManager);
   User user = new User("Adriano",  barManager);
    
   db.Store(user);
}

using (var db = Db4oEmbedded.OpenFile(databaseFileName))
{
   var query = db.Query();
   query.Constrain(typeof (User));
   query.Descend("Name").Constrain("Adriano");
   
   User user = (User) query.Execute()[0];
   Console.WriteLine(user.Manager.Manager.Manager.Addresses[0].Street);
}

Can you see the problem? No, I am not talking about Law of Demeter "violation" :) (By the way, if you are interested in this subject you can find a nice discussion here).

Again, if you have been working with db4o for some time I am sure you already spent some time debugging this kind of issue.

As always, the answer comes in a future post.

Have fun!

Adriano

May 16, 2010

Installing Nokia SDK on a Windows 7 box

Hi


As you can figure out based on the post title, I want to start to play with Mobile development using Java (no, I haven't gave up on .Net :); it just happens that I own an N95 and I want to write a little application for it1).


After downloading latest Nokia SDK I  tried to follow the steps in the documentation (IDEs for Java Development) but I just get the infamous error:


Cannot start Series 60 SDK for MIDP


while importing the device.


Thanks God, it was just a matter of "googling" for the error message and I got the following page


http://wiki.urban.cens.ucla.edu/index.php?title=Nokia's_Java_Platform_(Carbide.j)


which fixed the issue (I just search in my hard disks and found 5 copies of the offending DLL).


Well, since my daughter has just born I guess this project will run really slowly but I hope it will not stall :) 


Best


Adriano


1. I am planning to write an application that stores information about gym exercises in a db4o database. 





May 11, 2010

Project deployed

Hi


In the latest days I've been really busy with the deployment of the project formerly known as "baby 2.0" (by the way, the official project name is Gabriela). 


Last Thursday (May, 6) my daughter was born with 4.1 Kg and 52 cm. Of course my whole family if very happy and I an my wife are very proud :)


Following you can see some pictures of her:


 


   

That's it for now (I'm gonna to sleep :))

Best

Adriano

Mar 18, 2010

I am not dead. Not yet

Warning: Personal content ahead

I can hear someone screaming already: but it really looked like you have died! :)
Well, you know, I have been having to much work fun lately.

Also, more or less 7 months ago, I and my wife decided to start a new project, daughter 2.0, and since then we have been working hard to get the environment ready to the deployment (there are too many details in such projects deployment). 

At this stage we can say that the project is growing as expected and that we are looking forward to the deployment date.

As always we expect the maintenance phase to consume much more time/resources than the development phase, but we are more than willing to do the required investment so the project will be able to meet its goals; after all, this is our baby :).

Last but not least, as you can see, I am actually alive :). So, bear with me! As soon as I get some spare time I'll do some more posts!

Good to get back to posting!

See you all.


Aug 10, 2009

Did you know ? (Part I) - Executing sub-queries

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

Jul 25, 2009

What's wrong with this code(Part XI) - Answer

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

Jul 16, 2009

What's wrong with this code(Part XI) ?

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!