Thursday, September 15, 2011

Compiling Your Own Version of SQLite for iOS and applying some fixes

Adding your own version of sqlite for iOS is fairly easy task.
  1. Go to http://www.sqlite.org/ and download the latest sqlite amalgamation archive
  2. Extract it somewhere and add it to your Xcode project. You have several options here. You could copy it to your project folder, or link to it. You could also decide, to put it as a static library target and link it to your main target. It's up to you. You will need only sqlite.c and sqlite.h files.
  3. Apply some #defines you might need. For example:
#define SQLITE_ENABLE_FTS3
#define SQLITE_DISABLE_LFS
#define SQLITE_THREADSAFE 0
Then you can compile!

If you need more detail about this part of the process, you can find more detailed description here and here.

And then I hit a problem. I was testing on different simulator versions and found out that for some reason SQLite functions returned strange errors ( SQLITE_CORRUPT with number code 11 ) with some versions of the simulator, while with others, everything worked perfectly fine. After hours of debugging, I've found that the problem is in wrong file size, returned by a function called unixFileSize. Here is how it looks in my sqlite version:
/*
** Determine the current size of a file in bytes
*/
static int unixFileSize(sqlite3_file *id, i64 *pSize){
  int rc;
  struct stat buf;
  assert( id );
  rc = osFstat(((unixFile*)id)->h, &buf);
  SimulateIOError( rc=1 );
  if( rc!=0 ){
    ((unixFile*)id)->lastErrno = errno;
    return SQLITE_IOERR_FSTAT;
  }
  *pSize = buf.st_size;

  /* When opening a zero-size database, the findInodeInfo() procedure
  ** writes a single byte into that file in order to work around a bug
  ** in the OS-X msdos filesystem.  In order to avoid problems with upper
  ** layers, we need to report this file size as zero even though it is
  ** really 1.   Ticket #3260.
  */
  if( *pSize==1 ) *pSize = 0;


  return SQLITE_OK;
}
Here after a successful call to osFstat, buf.st_size contained wrong file size. This is clearly not a bug in SQLite. There might be several reasons for this to happen. Probably struct stat is different in terms of packaging or field sizes from the one compiled with some of the simulators. I don't know and since I cannot fix it in iOS Simulator (the power of closed source in action), I don't really care. What I can fix, is not to use fstat() and struct stat in this function. Here is how I changed the function using other Unix ways and do the job:
/*
** Determine the current size of a file in bytes
*/
static int unixFileSize(sqlite3_file *id, i64 *pSize){
  off_t pos, size;
  pos = lseek(((unixFile*)id)->h, 0L, SEEK_CUR);
  if (-1 == pos){
    ((unixFile*)id)->lastErrno = errno;
    return SQLITE_IOERR_SEEK;
  }
  size = lseek(((unixFile*)id)->h, 0L, SEEK_END);
  if (-1 == size) {
    ((unixFile*)id)->lastErrno = errno;
    return SQLITE_IOERR_SEEK;
  }
  if (-1 == lseek(((unixFile*)id)->h, pos, SEEK_SET)) {
    ((unixFile*)id)->lastErrno = errno;
    return SQLITE_IOERR_SEEK;
  }
  *pSize = size;

  /* When opening a zero-size database, the findInodeInfo() procedure
  ** writes a single byte into that file in order to work around a bug
  ** in the OS-X msdos filesystem.  In order to avoid problems with upper
  ** layers, we need to report this file size as zero even though it is
  ** really 1.   Ticket #3260.
  */
  if( *pSize==1 ) *pSize = 0;


  return SQLITE_OK;
}
As you can see I'm using lseek to get the file size and thus avoid the struct stat and fstat() usage. This fixed the problem for me and I hope this could spare some time to others too. Note that this fix is not portable and will not work in non Unix environment.

Monday, August 29, 2011

How to have great wait cursor animations for free


While searching for a "trivial" wait animation for one of my AJAX projects I've found a great online solution for the problem. It has been around for years now, but it's new for me and I decided to share it.

Introducing http://ajaxload.info/ a free AJAX load animation generator. It's great to have it around.

Here are some images I've created briefly as a showcase ..... well I guess they already have your attention :)







Thursday, August 25, 2011

Linking to Android Market applications on the web

While working on web version of Da Dictionary I've decided to add link to Android version. Web links to Android Market looks like this http://market.android.com/details?id=com.demosten.android.dadict where 'com.demosten.android.dadict' is the package name which is unique for Android Market. This seams to work well when opened from PC browser. However opening this link from Android is a different story. The best way to open it is directly in Android Market application which works with different URI scheme. It looks like market://details?id=com.demosten.android.dadict where again we see the same package name mentioned. While built-in Android browser plays it smart and open the link in directly in Market Application alternative browsers like Firefox does not do so and viewing web version of Android Market on an Android phone is far form what users expected to see.

My solution
<html>

<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script>
<script type="text/javascript">
$(function() {
  updateAndroidMarketLinks();
  // some more core here ... 
 
  function updateAndroidMarketLinks()
  {
    var ua = navigator.userAgent.toLowerCase();
    if (0 <= ua.indexOf("android")) {
      // we have android
      $("a[href^='http://market.android.com/']").each(function() {
        this.href = this.href.replace(/^http:\/\/market\.android\.com\//,
          "market://");
      });
    }
  }
});
</script>
</head>

<body>
<a href="http://market.android.com/details?id=com.demosten.android.dadict" target="_blank">Download for Android</a>
</body>

</html>
As you can see my solution is based on JavaScript and jQuery. The idea is to search for 'android' sub-string inside browser's UserAgent and if that is the case - replace HTTP URI part with Android Market URI part, inside all links.

I believe a JavaScript only version is not hard to do, but I prefer to use jQuery.

Thursday, March 17, 2011

iPad 2 launch event impressions

I've finally found some time to watch Apple's iPad 2 launch event. I liked it. It looks like a great product and as usual, Steve and company presented it very smoothly. Someone should write a book "How to present like Apple" here!

One thing that puzzles me is why did they mentioned the competition so many times? If you are so convinced, you have the greatest product around, why should you bother even mentioning any competition? The history will probably repeat itself. The first phones that caught up with iPhone appeared 2 years later and the first which were (in my opinion) better, after 3. I believe the same will happen with tablets. Saying that, it looks to me like Apple are starting to feel the pressure now, but I don't think they'll be matched this year. Meanwhile I'm adding iPad 2 to my wish list.

Sunday, October 10, 2010

Stages of adopting open source mind-set


These are stages I observed for years from both people and organizations. I might miss something here, but before you think "this is not me/us" think again. I'll use person's perspective, because it always comes to a person. Be it your friend or some big corporate CTO or architect.

  1. Ignorance: open source doesn't exist. If anyone mentions it, you tell yourself "there are dragons there", "it is not secure", "licensing is viral", "I know this guy that once used open source and got sued" etc. Also you think, you can do better on your own.

  2. Waking up: you are doing this great PNG display library for months now and you have only 20 more known bugs to fix before you can start working on your great SSL implementation then some friend comes by and asks "have you tried libPNG and OpenSSL?". You try them and they seams to work. You start reading licenses.

  3. It's a wonderful world v1.0: The sun shines again. Now you know much about open source licenses. You are using as much open source as you can. In fact it's something like a big well and you can take as much as you like right? You start to understand some of the ideas behind. You also have a strong opinion about how those projects should be managed and what needs to be done next there.

  4. Open your heart: It's a big well but wouldn't it be great if you add something to it? You are looking at your own projects and start thinking - "should I open them?". You decide to try with caution. You open couple of your most unimportant projects. You select them because no one have time for them in hope that "it's a big community, there should be someone willing to add improvements". Now you consider yourself a full grown open source citizen and so is your company.

  5. No love for me: No one wants to work on your open projects. In fact no one cares. You are wondering what's wrong with the community. Looking at other open projects and comparing them to your own, you can see some differences. Maintaining an open source is not an easy task. Getting support from community comes with a price. And if you don't like and care for your projects, others won't too.

  6. It's a wonderful world v2.0: You start opening only your significant projects. Selecting those you are sure many people will find useful. It is important for those projects to have some unique features and/or be clearly better than similar open source projects. They need to be well documented, with clear license and build instructions. Some samples are useful too. Once you have that you will get community support. You understand that open source doesn't necessarily mean nobody gets paid to work on it. It just means it is open for others to look at the code and use it, and they might contribute. Now you can decide should you be the main contributor or just step out and leave it to the world to handle from now on.
     

Thursday, June 24, 2010

A smart phone dream of mine

I'm in a smart phone world for 2 years now, changing several phones and platforms, but this dream of mine is older. It's not a smart phone dream, it's a personal computing dream. I dream of having my PC with me wherever I go and a smart phone is a way to achieve it. In my dream there are peripheral stations (PS) consisting of bigger display (monitor, beamer ...), input devices (keyboard, mouse, joystick ...) and some power supply. You come to your home, plug your smart phone to your home peripheral station and work with your PC. You go to work plug your smart phone to your workplace's peripheral station, switch to work profile and work with your work PC. The device is one and the same you could switch profiles and even operating systems if this is needed. In my dream there are also public peripheral stations, where you could plug your smart phone/PC to work more comfortably, while recharging it at the same time. Those stations cannot harm your PC in any way as they don't have any storage to store viruses or any personal data. All storage is with you. Network connection can be provided by your mobile operator or by the station, it is your choice. At some point, when wireless connections become fast enough and power supply is taken from the sun or from your body heat and movement (for example), you could connect to the peripheral station without a wire. And of course you could always use the smart phone screen and keyboard to work with, in case there is no (free) peripheral station around.

The good news is this is coming closer to reality. Here http://sven.killig.de/android/N1/2.2/usb_host/ you can find a sample of taking the first steps in this direction.

Wednesday, May 19, 2010

A development learning story...

So here I am - trying to learn programming, surrounded by several of my university colleagues who know more about it than I do. I want to be better and I am getting better. Bit by bit. I start creating simple programs from scratch. No internet yet, no google. I’m searching inside several help systems I can get my hands on and I improve myself day after day. Time passes; I start to skip some of my university classes. Instead, I’m staying at home creating from scratch more and more complex programs. My colleagues are helping me. Sometimes with information, sometimes showing off, making me want to be that good and sometimes with words like “I’ve listened to you for the past 30 minutes and didn’t laugh because I know you don’t know things … but you are not right”. And this makes me want to be better again and again. I’m starting to isolate parts of my code making “libraries” of reusable code. Then get better at making libraries. I know how to make it extendable, how to document it and how to reuse it. Now I’m better than most of my colleagues and equal to the rest of them. They accept me, but I accept no one. No one’s code is good enough to be used. I’m creating everything I need and I’m good at it. I believe I can create something like Windows 3.11 for about 3-6 months all by myself and I believe myself. Slowly I’m starting to realize that things are deeper than they look and I have to start trusting other people’s code in order to create complex programs. I’m also starting to understand that more complex doesn’t make it better and now I’m creating simpler code. Make methods and functions smaller, make code blocks as clear as possible and always strive to keep it simple (but not stupid!). Somewhere in between I’ve started switching programming languages. Going from Pascal to Assembly, mixing it back with Pascal, then C, then C++, a little bit of Delphi, then Java, some Perl and the list goes on. With time I’ve switched programming APIs and concepts too: DOS, Windows, Embed development, POSIX. All of them came with their own charms and specifics. At this time better programming books got published, explaining concepts like design patterns. Too late, I’ve already discovered all these patterns by myself. It was funny someone spent time to collect those obvious ideas and give them odd names. I still believe design patterns book made more harm then it helped. People need to discover those things by themselves or they won’t truly understand them and know where to use them and more important when NOT to use them and why. Then I’m discovering next “library” level – modularity. It is dynamic, it can be switched on and off on the fly, it can be replaced with fixed/newer version without recompiling the rest of the code. After some concept polishing and learning how others do it, I’m starting my own product based on my own modular concept. It is small, it is clean, it is clear. It is a great piece of technology and none of my clients cares about this. Slowly I start realizing, that though modularity is great, it took at least 50% of my development time to plan it, make it that great and support it in the future development. This time doesn’t pay back – really! I also start understanding that I seldom use any piece of my code twice. I’m learning as I go and I almost always know a better way to do it after several months. The way sometimes involves using a new library and sometimes it’s just me knowing more. In either case I get my old code and rip a good part of it creating something new, instead of reusing it.

So here I am - creating more and more complex software, using the best I can find pieces of other people’s code and creating the rest on my own. Always try to keep it simple (and not stupid). Keep it small and clear. Don’t make a block of code do more than one thing and don’t make it bigger than one screen can display. Use comments sparingly and describe your context, reasons and ideas there. Don’t make reusable code unless you’re creating a library on purpose. And programming languages - they are just a way to express yourself. Programming concepts like functional and object oriented programming too. They don’t really matter. What matters is to understand the core idea behind them in order to use them effectively. Once you understand it, you understand that it is possible to create a complex solution with plain C as easy as you create it using Java, C#, C++ or whatever.