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!

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

Jun 19, 2009

Hexadecimal Control Viewer DotNet

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

Jun 18, 2009

Elementary my dear Watson


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

Jun 13, 2009

On test writing discipline and gains

Hi.

Let's start this post with the usual disclaimers :). Actually, I have only one: Everything discussed here is related to my own experiences with unit testing and/or TDD in the last years.

In fact, I have been in contact with some sort of more formal testing procedures for some time now; in the early days it was more a desperate act trying to avoid SDD (sorry if I use potentially valid acronyms here), i.e, 'Shame Driven Development'. Since most of my code have no tests at all (other than the usual driver application that covered only the changes being applyied at the moment), it was not uncommon to have some developer, tester or even final users approaching me and complaining about some broken feature in a just released version of the module I've worked on (whence the shame). Of course the usual problems of lacking good tests were plain visible: resistance to refactor / change code, lack of confidence whether a piece of code was good enough or not, no sensible metric to declare completeness, regressions all over the place, etc.)

After understanding (thanks to my coach :) the importance of having a well developed ( one that values readability, maintainability, expressiveness, in the sense of making clear test intents, completeness, etc) test suite, finding the time and motivation to write such tests became easier. Even though understanding the benefits of having such tests, the urge to get something working, and so that it could be shown (to managers, clients, whoever), made me tempted to skip the test writing (remember, I haven't get into the TDD mind set yet, so tests were seen as a post development phase).

In these early days, most of my teammates had little or no idea of the concept of unit testing and it was hard to convice them that it worths the time dedicated to write such tests. Anyway, sometimes I took the burden upon myself and wrote unit tests (even though no time was allocated to that). Of course everybody noticed that my code was less buggy and that I was less concerned aboud changing it :)

Some years have passed and even though doing my best to start my coding sessions with a test I must admit that I am not a TDD practitioner yet, at least not in the strict sense of the definition. This becomes clear when it comes to my personal projects: most of them have no tests at all :(.

But thanks to some embarrassing episodes (related to one of these personal projects) (and to my coach :) I had finally decided to do "the right thing(tm)" and I am writing the tests I should have writen long before :) (guess what, I've already found hidden bugs). I am even using a nice mock library for .Net called Moq.

Of course I am starting to see the pays off of pursuing this goal :)

Best regards (and have fun!)

Adriano

Jun 10, 2009

How to not ask for help on online forums


Hi.

Well, you know, being a software developer automatically entitles you as your "family IT manager"; there's nothing we can do about it:). That's the way life is.
But if you are involved with an open source project chances are that you participate in that community either asking or answering questions (or both) in project's forums, mailing lists, etc. In the following lines I want to present some points I believe may make the difference between getting an effective answer or getting your question forgotten in some dirty corner in the internet.
  • Screaming for "help" like the good girls on movies is not effective.

  • Don't expect people to do your work. Don't get me wrong, but how many times, for whatever reason, we just cry for help without even trying to figure the problem out first?

  • A simple search in the internet before asking will at least allow you to be more precise or even eliminate the need to ask at all (chances are that someone else already faced the same problem/doubt we are facing). In the open source world there are lots of different places we can look for more information, for instance:
    • Project forums
    • Bug tracker / Issue system
    • Mailing lists
    • Source code (why not :)
    • etc.

  • Focus on what you are trying to achieve not in the problem: consider the possibility that you may be attacking the wrong problem.

  • Provide as much context as possible:
    • Calling your mechanic and saying: "You know what? may car isn't working" is a little bit vague and won't be that helpful. Probably saying: "I turn on the ignition but nothing happens" would be a little bit better (but not that much); providing more information, something like: "I checked it out and I can see that I am not out of gas; also I can see that the battery looks to be ok, but when I try to start the engine nothing happens other than the indication lights turning on" would be much better. I think that you got the idea :)

    • Environment (software version, etc)

    • If you have a stack trace, please, don't hide it from your buddy.

  • Be friendly (in general people is earning nothing, other than personal satisfaction, by helping you). Above anything, don't behave as if the person trying to help you had the obligation to provide you an answer/fix.

  • Reproducible behavior is a lot easier to debug / fix, so, if possible, prepare the smallest test case that triggers the problem. Even better, if you really want to rise the chances of people helping you, use the same test framework used in the project.
I do believe these "principles" apply equally well whenever you are about to submit a new bug/issue report to your favorite project bug/issue track system. I mean, I doubt that filling such systems with duplicated and/or misleading, inconsistent, etc. entries will help anyone in making a better project. 
So, next time we fell compelled to ask for help let's refrain ourselves and first try a little bit harder; I am a fierce believer that this is the best way to learn (trying to fix it ourselves instead of just asking); as a side benefit we'll not disturb other developers letting them to use their time to improve the project  instead of scanning / answering questions that was already answered before.

Last but not least, I don't want to give the false impression that I am against asking for help; I just think that we ought to keep this approach as our last resort, i.e, to situations where it's really not possible to figure out the problem alone (for instance, when a specific behavior/API/whatever is not documented and no information can be found, at least not easily found).

Of course this is not an exhaustive list, so, feel free to comment :)  

Best regards (and lets have fun !)

Adriano

Jun 6, 2009

Another day in a developer's life....

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 a future post :)


Have fun! 


Adriano

Mar 23, 2009

Db4o with Visual Studio 10 / .Net Framework 4

Hi.

When Microsoft announced they would make available VS 2010 CTP I got curious about how easy (or hard) it would be to compile / run Db4o and also how OMN would behave in this early CTP (would it just work, without even require a recompilation? If not, how easy/hard it would be to make it work if possible at all, etc).


Well, yesterday I managed to download the CTP; after extracting the files (24 Gb!!) I just took OMN 2008 installation and give it a try. It was really amazing. The only change I've applied was to update the file %ALLUSERSPROFILE%\Application Data\Microsoft\MSEnvShared\Addins\OMAddin.addin in order to change the target VS (OMN 2008 will set it to 9.0 but VS 2010 is 10.0). 


After this change I just fired up VS and OMN addin was there, working with no issues (as far as I tested :)) as you can see in the screen shot bellow. Cool.



Next step was to load Db4o 2008 solution file; VS 2010 asked whenever I'd like to convert the solution/project files to the newer version; I just consent to that and when it finished converting I just run Db4o Tests. 

This time some tests failed due to missing jars (I didn't run a full build) required to run Java/.Net compatibility tests; besides that expected failure,  only one test failed (I just disabled it for now).


My next steps will be:

  1. Try to understand / fix the falling test.
     
  2. Prepare the environment to at least run the target "build-before-checkin"  defined in build.xml (and uncomment any test commented out to make the tests pass).

  3. Reason whenever it makes sense to use some of C# 4.0 / .Net Framework 4.0 new features (for instance dynamic types) and how Db4o handle them.
Since these will require more time to investigate / test I'll leave them for a forthcoming post.

Adriano

Mar 21, 2009

Benefits of working from home - Epilogue

After 9 posts in this subject (BTW, I have written this post long ago) I am going to finish it... and the big question is:

Did it worth?

Well, to answer this question I pondered on various aspects: It allowed me to move to a smaller city, closer to my wife's parents, a less violent, less expansive
city, etc; it gave me the chance to spend more time with my family and a lot more benefits!

So, IMO it really worth the move! Even missing some "usual work style", I am pretty happy working with very smart people, in a really cool product, applying really nice development methodologies and last, but not least, being able to organize my own time :).


I don't know how long I'll be working with these stunning guys, but I do hope I could be there for a long time ;). There's just so many things to learn yet!

That's it ;)

See you all.

Adriano

Mar 10, 2009

Automating Skype through COM

Wow.. finally a technical post again :)

Those of you who knows me knows that I am a firm believer of component technologies.

Personally I really appreciate Microsoft's COM technology; ok, it does has it drawbacks (as everything in life) but when used correctly it proved to be a very powerful way to support software automation and extensibility. Let me briefly explain what those funny words means for those who don't know yet.

Basically, software automation is the process of a software controlling another one. For instance, if you have Microsoft Office installed it's possible to write a program (even a JavaScript script) that creates a Word Document through automation, i.e, your program may "control" word (and Excel, Power Point, etc). This kind of flexibility can be very helpful in some scenarios.

By extensibility I mean ways of extending a given application. A good example is Windows Explorer; it's possible to add new items to a context menu (in the same way 7-Zip and many other applications do) simply by implementing an specific COM interface (and registering your component of course).

These are just 2 examples of what's possible; of course other softwares also support some level of automation (for instance Adobe Acrobat).

In this post I just want to talk (again, briefly) about Skype and how it's possible to extend it through COM (Skype also supports automation through Java, XXX, etc).

First let me just explain that the possibilities are infinite; what you may want to do with automation is not my business :); all I can say is that if you think a little bit you'll be able to find some nice use for skype automation.

For instance (as I said in my last posts) I use Skype heavily on my work to communicate with other team's members. At least once per week we do a Skype meeting in order to decide what we're going to do in that week; to manage these tasks we have a "queue" of tasks in our Jira installation.

One annoyance during this meeting is that once someone decide he wants to take a specific task the process involves at least 2 steps: to announce in the chat meeting and going to the browser to update Jira.

Since it's possible to automate Skype I wrote (to be more precise I am debugging it right now) a "plug-in" that simply keeps listening all chat messages and react accordingly for specific patterns; for instance if I want to take a task (let's say TSK-1) I may just type:

$jira assign TSK-1 myself

This way I announce to the team and update Jira at once :) (I don't need to go to the browser anymore)

The plugin is "smart" enough (through configuration) to figure out who I am ("myself") and to go to Jira (through a WebService) and update the specific issue (task).

And this is only a basic example about what can be done (the sky is the limit :).

For more information about Skype automation visit
https://developer.skype.com/.

If you want to take a look into this plugin, just grab the code at: git@github.com:adrianoc/binboo.git or browse the code online at https://github.com/adrianoc/binboo (just keep in mind that there're lots of assumptions/dependencies to our Jira installation but I guess one can learn a lot about how to integrate to either Jira or Skype). 


See you.

Adriano

Jan 21, 2009

WIX Tips

Hi.

Since I have been playing a lot with MSI installers latelly and I'd like to share two tips with those authoring Windows Installers with WIX:
  • You can get a lot of information by running your installation package through msiexec:

    msiexec /i CustomAction.msi /lvx log.txt

    The command above just runs CustomAction.msi logging everything including the kitchen sink :)

  • You can use 7Zip to open msi files (and ofcourse, extract content from it)
Happing programming ;)

Adriano 

Jan 7, 2009

First impressions of Windows 7

Hi,

As a computer addicted I decided to download Windows 7 Beta 1 (32 bits) and give it a try (if you are interested, just search for "Windows 7 Beta1" in your favorite search engine and I am sure you'll find your way :)

In this post I want to present my first impressions about it. Please, note that I am not an expert in this subject and also that this is just my opinion based on my perception without any pretension regarding "data" accuracy.



I need to admit that I am impressed about it. My first impression is that it is way faster than Vista when running on the same machine; at least it is pretty responsive. Bellow you can find a list of items that caught  my attention and won my respect (at least for now):



  • Fast Installation: ~ 20 min for a full install.

  • Few prompts during installation.

  • No problems with device drivers at all (Video, audio, keyboard, etc)
    • Some devices already have preliminary versions for Windows 7
      I guess that this is more a result of not introducing deeper changes to the driver model (Vista introduced really deep changes there).

  • There are some compatible antivirus already.

  • Looks really fast on a relatively old hardware

  • I really liked the UI changes (even being minor changes).
     
  • Just a few UAC prompts
    • Using it for some time I have seem UAC prompts only for software installation.

  • IE 8 is not as fast as I'd like it to be. (But I've already installed firefox)
 Bellow you can see a screen shot.


Well, that's it for now.


Adriano

Storing PowerShell objects into a Db4o database

Hi,
First of all, Happy New Year :)
If you use both PowerShell and Db4o you maybe interested in this post.
Best
Adriano