Frans Bouma (founder/developer of LLBLGen) "discovers" Quino

Encodo Systems AG started work on its metadata framework Quino in late 2007. We've used it successfully in many projects, from Windows desktop applications to standalone servers, Windows services and web sites. It has grown considerably since its inception and the core concept of keeping the focus of an application on its metadata has stood the test of time quite well.

The recent article Code-first O/R mapping is actually rather silly by Frans Bouma recounts how the lead developer and architect of another popular ORM LLBLGen Pro, has also recently "discovered" the benefits of the metadata-first approach.

He writes,

Starting with code in the form of entity classes is equally odd as starting with a table: they both require reverse engineering to the abstract entity definition to create the element 'on the other side': reverse engineer[ing] the class to the abstract entity definition to create a table and the mappings is equal to reverse engineering a table to a class and create the mappings. [T]he core issue is that if you start with a class or a table, you start with the end result of a projection of an abstract entity definition [...]

What if that abstract entity definition which was used to create the class or table was in a model which contained all of the domain types for the domain used in the software to build? [...] it would give a couple of benefits: you can create overviews of the model and more importantly, changes in the domain can be applied directly into the model which then ripple through to classes and tables in the right form [...] (Emphasis added.)

He describes the core tenets of Quino rather well: starting with the metadata avoids diluting the domain model with the limitations of a projection domain (classes, tables, etc.). This has been borne out by our experience working in exactly this manner for the last several years.

The ORM in Quino is only a satellite component that leverages the centrally defined metadata just as many other components do. The programmer defines the metadata of the domain model and Quino provides tools to do many tasks automatically:

  1. Create or update a database schema
  2. Generate business-logic classes (primarily C# but it could be JavaScript or indeed any target language where code would benefit from strongly typed domain classes)
  3. Select/create/update/delete data in one or more databases
  4. Generate standardized user interfaces for multiple platforms
  5. Integrate with reporting engines and designers
  6. Generate UML diagrams
  7. ...and much more...

I heartily encourage Frans to continue thinking in this direction. He will be rewarded greatly for it.

v1.9.2: Bug fixes for 1.9.1 -- Reporting fixes and improvements

The summary below describes major new features, items of note and breaking changes. The full list of issues is also available for those with access to the Encodo issue tracker.


Breaking changes

  • None
Entity Framework Generated SQL

This article originally appeared on earthli News and has been cross-posted here.

Microsoft just recently released Visual Studio 2013, which includes Entity Framework 6 and introduces a lot of new features. It reminded me of the following query that EF generated for me, way, way back when it was still version 3.5. Here's hoping that they've taken care of this problem since then.

So, the other day EF (v3.5) seemed to be taking quite a while to execute a query on SQL Server. This was a pretty central query and involved a few joins and restrictions, but wasn't anything too wild. All of the restrictions and joins were on numeric fields backed by indexes.

In these cases, it's always best to just fire up the profiler and see what kind of SQL is being generated by EF. It was a pretty scary thing (I've lost it unfortunately), but I did manage to take a screenshot of the query plan, shown below.


It doesn't look too bad until you notice that the inset on the bottom right (the black smudgy thing) is a representation of the entire query ... and that it just kept going on down the page.

How to fool people into giving up their email address

This article originally appeared on earthli News and has been cross-posted here.

On Codecademy, you can learn to program in various languages. It starts off very slowly and is targeted at non-technical users. That's their claim anyway -- the material in the courses I looked at ramps up pretty quickly.

Anyway, the interesting thing I saw was in their introductory test. It struck me as a subtle way to get you to enter your email address. I'd just recently discussed this on a project I'm working on: how can we make it fun for the user to enter personal information? The goal is not to sell that information (not yet anyway, but who knows what the future holds), but to be able to enhance -- nay, personalize -- the service.

Personalizing has a bad reputation but can be very beneficial. For example, if you're using a site for free and you're going to see offers and advertisements anyway, isn't it better to enter a bit of data that will increase the likelihood that offers and ads are interesting? Each person can -- and should -- decide for the themselves what to make public, but the answer isn't always necessarily no.

How Codecademy gets your email


Here they teach you how to use the "length" method by measuring your email address. Sneaky. I like it.


Even if you don't given them an address, they re-prompt you to enter your email, but it doesn't come across as pushy because you're taking a test.

I thought that this was pretty subtle. Because of the context, people who would ordinarily be sensitive to giving up their email might not even notice. Why? Because they want to answer the question correctly. They don't want the site to judge them for having entered something wrong, so they do as they're told.

Is Codecademy collecting emails this way? I have no way to be sure, but they'd be silly not to.

How to drag rewind and fast-forward into the 21st century

This article originally appeared on earthli News and has been cross-posted here.

The most difficult technical problems to solve are the ones that you don't notice. The workflow and tools to which you've become accustomed are terrible, but they're so ingrained that you might actually find yourself unthinkingly defending them because that's just how it has to be.

Below I take a shot at designing a better user experience for a common feature: rewinding or fast-forwarding a video recorded on a DVR.

Why is your DVR's fast-forwarding feature stuck in the past?

Fast-forwarding and rewinding digital movies is one of those things.

Many people have DVRs now -- provided, often enough, by the cable company itself -- but they often function as if customers were still juggling tapes instead of switching between files on a hard drive. While there is no technical hurdle to making this process better, I acknowledge that there are probably very important albeit tediously prosaic advertising reasons for keeping fast-forwarding not just primitive, but almost deliberately broken.

Despite the strong likelihood that this feature will not be improved for the reasons stated above (i.e. that the exorbitant monthly fee that you pay for your content will continue to be supplemented by advertising revenue generated by your captive eyeballs), it would still be fun to imagine how we could make this feature better.

Use cases

The most obvious use case for fast-forwarding is to skip commercials in recorded content: that's just reality. Though the cable companies and networks would dearly love for everyone to take their medicine and watch all of their advertisements, users would dearly love to just watch their content without the ads. That is often the reason that they recorded the content in the first place.

Another use case is to scrub forward in longer sports events, like cycling or the Olympics. The user generally doesn't want to watch six hours; instead, the user would like to skip forward 2.5 hours, watch 15 minutes, skip another hour, watch 30 minutes, skip another hour and watch the rest, all the while skipping commercials in between. Often the user doesn't even know how far they want to skip; they need to see the content at various intervals in order to see where to stop. This is currently achieved by just scrubbing through all the content sequentially.

This is all not only a tedious amount of work but also takes much longer than necessary: even at the top speed, the fast-forward feature takes long minutes to skip two hours of content. This is ridiculous, especially when most of us have seen it work at least marginally better on a computer, where one can skip large chunks of content and reliably jump to a specific position in the recording. The system described below could improve the experience for computer-based media players as well.

What's the problem?

Fast-forwarding is a pain because, while you'd like to jump forward as quickly as possible, you have to be fast enough to stop it before it's gone too far. This is old-school technology from the days of the VCR when there was only one read-head per device. Now there's a digital file that the machine can easily read and render thumbnails from anywhere in the data stream.

My media box from UPC Cablecom offers the standard controls for scrubbing: play, pause, fast-forward, rewind. When you press rewind or fast-forward, it moves between five speeds, skipping forward or backward faster with each level. When you've got it on 5 of 5, you skip commercials or content very quickly, but you're also extremely likely to skip over content you wanted to watch.

The standard pattern is to fly forward, slam on the brakes, then backtrack slowly, overshoot again -- but not by as much -- and then finally position the read-head about where you want it, watching the final 20 seconds of commercials or station identification that you couldn't avoid until you finally get to the content you were looking for.

There has to be a better way of doing this.

Making it better

The idea of five speeds is fine, but we should be able to take the twitch-gamer component out of the experience. And this is coming from someone who used to be a pretty dedicated gamer; I can't imagine what this system feels like to someone unaccustomed to technology. They probably just put it on the slow speed -- or don't bother fast-forwarding at all.

What about a solution that works like this: instead of changing speed immediately, pressing rewind or fast-forward pauses the stream and switches to a scrubbing mode. The scrubbing mode is displayed as a screen of tiles -- say 5x5 -- each tile representing a screenshot/thumbnail from the stream that you're watching.

The thumbnails are chosen in the following manner. If you pressed fast-forward, the thumbnail for your current position is shown in the upper left-hand corner. Subsequent tiles are chosen at 5-second intervals going forward in the stream. Pressing the fast-forward again increases the level -- as before -- but, instead of speeding through the stream, it simply chooses new thumbnails, this time at 10-second intervals. Press again to switch to 30-second, then 1-minute, then 5-minute intervals. At the top "speed" the bottom right-hand corner shows a thumbnail 24 x 5 minutes forward in the stream.

Rewind has the same behavior, except that the current position is shown in the bottom right-hand corner and thumbnails proceed from right-to-left, bottom-to-top to show the user data in the stream before that position.

Once the user is on this screen, he or she can use the cursor to select the desired thumbnail and refocus the screen on that one by clicking OK. In this way, the user can quickly and reliably use the fast-forward or rewind buttons to switch the granularity to "home in" in on a particular scene. All without any stress, missteps or a lot of senseless back-and-forth scrubbing. And all without having to watch hardly anything -- a few seconds at most -- that the user doesn't want to watch.

When the right scene is selected (to within 5 seconds), the user presses play or pause to continue watching from the newly selected position.

Players like Roku have a "jump back ten seconds" feature that's quite useful, but the system described above makes that sound utterly primitive and limiting.

Going beyond five intervals

It is no longer necessary to have only 5 fixed intervals either. Perhaps the default interval (user-configurable) is 2 seconds, but that's only the center of a scale with 10 steps, so the user can drop down to 1-second or 1/2-second increments as well.

Positioning the current scene in scrubber mode

The system described above moves the default location of the current scene, depending on whether the user pressed rewind (bottom-right corner) or fast forward (top-left corner). Another approach would be to ignore which button was pressed and to always show the current scene in the center of the grid, with thumbnails showing history as well as future in the recording. Further presses of rewind and fast forward increase or decrease the amount of time represented by each thumbnail.

Rendering thumbnails

If the software takes time to render the thumbnails, it can do it asynchronously, rendering thumbnails to screen as they become available. Showing the time under the thumbnail would be massively helpful even without a thumbnail. The user could easily jump ahead 4 minutes without any adrenalin at all.

This should be a huge problem, though. Whenever the user opens a recording, the software can proactively cache thumbnails based on expected usage or default settings.

Learning HTML5 basics

We recently put together a list of links and references that would be useful for anyone interested in getting up to speed on HTML5 development. These are what we consider to be the absolute basics -- what you need in order to even begin discussing more complex issues of architecture, tiering, data-binding, MVC and so on. So, imagine you are participating in an HTML5 course at Encodo -- you'd probably get something like the following article in order to make sure you're ready.

HTML5 prerequisites

This section describes the knowledge prerequisites for course participants.

Since the course includes a significant hands-on component and will discuss the advantages and disadvantages of architecture-level concepts, a minimum level of proficiency in some basic topics is required.

  • Prerequisites include online resources that can be used to gain the minimum required level of proficiency. The resources are there to help participants learn about a topic. Participants that are already familiar with a topic do not need to use them.
  • Familiarity means I know what CSS selectors do and know a few of the basic ones. It does not mean I know every CSS selector by heart nor does it mean I read an article about CSS five years ago. Participants are expected to judge their own proficiency honestly and prepare accordingly.
  • Required resources are generally a few pages that can be read in 1015 minutes. Optional resources are helpful for learning more but arent required reading.


The DOM (Document Object Model) is the data structure on the client side that is rendered in the browser. A participant must be familiar with the basic tags and structure of the DOM as well as common attributes and events, including which ones are new to and deprecated in HTML5.




Participants must be familiar with the basic syntax and units. A working knowledge of how the basic selectors are applied to elements in the DOM is also required. Knowing how style cascade and override other styles (specificity rules) is a plus.




It is assumed the participants will be proficient in at least one programming language. An awareness of the common pitfalls and quirks of JavaScript is required: that it is untyped, has a very loose definition of objects and inheritance, and that web apps written in it tend to be quite functional and event-based in nature.




jQuery is an industry-standard library that binds HTML, CSS and JavaScript. Participants should be know how to use jQuery selectors use a CSS-like syntax to select elements from the HTML DOM, attach events to those elements and traverse to other elements in the DOM (e.g. children, siblings, etc.).



Browser compatibility

All modern browsers support the basic features outlined in the sections above. The site is useful to for finding out on which browsers the more advanced features are supported.

Practice sites

The following sites provide online sandboxes where participants can enter HTML, CSS and JavaScript to test it without installing or executing anything. They all allow examples to be saved for sharing.

A list of lesser-known OS X keyboard shortcuts

This article originally appeared on earthli News and has been cross-posted here.

The post Please share your hidden OS X features or tips and tricks yielded a treasure trove of keyboard shortcuts, some of which I knew and many that I'd never heard of or had long ago forgotten.

I collected, condensed and organized the ones I found the most useful below.

Finder & Open/Save dialogs

  • (-cmd) + (-shift) + G shows a location bar where you can type a path (/ or ~ also works in Open/Save). This text field supports ~ for the home directory and has rudimentary tab-completion.
  • (-cmd) + R reveals the currently selected item in a new Finder window.
  • (-cmd) + (-opt) + L selects your ~/Downloads folder.
  • (-cmd) + (-shift) + > shows/hides hidden files and folders (Open/Save dialogs only).
  • Dragging and dropping a file or folder into an Open/Save window re-targets that window on that file or folder

Managing applications

  • Press (-cmd) + tab to cycle through open applications.
  • Press (-cmd) + ~ (or < depending on keyboard layout) to cycle through open windows in the currently selected application.
  • While cycling, you can press q to quit the highlighted application or h to hide it
  • Press (-cmd) + (-opt) + esc to show a dialog that lets you force unresponsive applications to quit (you can even relaunch the Finder)
  • Hold down (-cmd) while clicking a dock icon to reveal that application in the Finder

Managing your Mac

  • Hold down (-opt) while clicking the "apple" menu on the top-left to execute commands (e.g. "Log out", "Shut down") without a confirmation dialog
  • Press ctrl + (-cmd) + (-opt) + (-eject) to shut down
  • Press (-cmd) + (-opt) + (-eject) to put the computer to sleep
  • Press ctrl + (-shift) + (-eject) to put the display to sleep
  • Press ctrl + (-cmd) + (-eject) to restart


  • (-cmd) + (-shift) + 4 lets you select an area to highlight and saves the screenshot to the desktop
  • (-cmd) + (-shift) + 4 + space lets you select an entire window, the dock, menu bar, etc. This will also include the drop shadow with transparency in the PNG screenshot.
  • Hold down ctrl with either of these to copy to the clipboard instead

Volume controls

  • Hold down (-shift) while adjusting the volume to mute the volume-changing sound (useful when adjusting volume during a call).
  • Hold down (-shift) + (-opt) while adjusting the volume to adjust in quarter-increments.
  • Hold down (-opt) while clicking the "sounds" menu-bar item to show a menu that lets you select the input/output devices without opening preferences

Screen & Brightness

  • Hold down (-shift) + (-opt) while adjusting the brightness to adjust in quarter-increments.
  • Hold down ctrl while scrolling with two fingers or the mouse wheel to zoom in/out on the entire screen
  • Hold down (-opt) while clicking the "bluetooth" or "wi-fi" menu-bar items to show a menu with more details about your connection, including options to show/generate diagnostics.
  • Hold down (-opt) while clicking the "notifications" icon to toggle it on/off
Including PDF in web sites

At first glance, this seems to be a pretty easy topic since PDFs are everywhere and can be found in almost every bigger website. But in most cases, PDF files are just linked for download and not embedded directly in the site. If the user clicks such a link, the browser decides what to do with the file: Just download to the file system or display a preview in a new tab or window. This also works pretty well for mobile devices since there are PDF readers for almost every platform.

But what if we want more than this, like embedding the document in the website and jumping to a specific page? The first part of this is very easy: We can use an iframe and set the location to the URL of the PDF.

<iframe src="document.pdf"></iframe>

This works fine on a desktop browser like chrome as it fits the width of the PDF to the width of the iframe:


But when we open the same page in mobile safari, it looks like following:


The PDF is not scaled and much worse: You can not even drag the document around. In short: This form of embedding PDF in websites is completely useless on iOS. Investigating deeper on this, it turns out that there is no way to fix this issue with a pure HTML / CSS solution.

Another solution that is worth looking at is pdf.js originally intended as a Firefox plugin to display PDF files in a platform-independent way. It renders PDF files into canvas elements using nothing more than pure JavaScript. In the hope that this will fix our PDF problem, we tried to include this JavaScript library in our web application. This worked fine for small- to medium-sized PDF files in desktop browsers as well as on mobile safari. But when we tried to display PDFs with complex content or more than 100 pages, we quickly ran into some limitations of this library: The rendering of huge PDFs was painfully slow and failed completely in some cases. I personally like this approach as it provides a platform independent solution which can be easily included in web applications, but it seems that it's just not ready right now. But maybe in a couple of months or years, this will be the way to go for displaying PDFs in web applications.

Another approach to fix this is to convert each page of the PDF into a PNG image. This approach is used widely on the web; for example by google books for the preview function. This approach is technically easy and things like zooming or jumping directly to a specific page can be implemented with a couple of lines of JavaScript. But one of the big drawbacks is that text is not submitted as text but as an image. This increases the transferred data size significantly which is, on the other hand, bad for mobile devices with their typically low bandwidth. To address this there are techniques like using the offline-application cache, which should definitely be kept in mind when using this approach.

After many hours investigating this topic, we ended up using the approach to include single pages of the PDF as PNG images in our web application. This requires that the PDF files be prepared server-side. Also, we implemented a dynamic-load algorithm which loads the images only when they are visible on the screen. This allowed us to display big documents without overburdening the video memory or the bandwidth of the mobile device.

v1.9.1: Bug fixes for 1.9 -- WAN speed, deadlocks and connection pooling

The summary below describes major new features, items of note and breaking changes. The full list of issues is also available for those with access to the Encodo issue tracker.


  • QNO-4201: Improved WAN speed by adding connection-pooling to avoid high connection setup costs
  • QNO-4233, QNO-4239, QNO-4241: Fixed some deadlock and connection-exhaustion issues in more complex models/data structures
  • QNO-4260: Upgraded DevExpress component library to v13.1
  • QNO-4246, QNO-4247: Made several improvements to object-graph management to improve identity/reference handling
  • QNO-4270, QNO-4278: Made some schema-migration improvements to support more conversions and constraint/path types

Breaking changes

  • Removed RemoteMethodCallException and added CreatePayloadException
Ignoring files with Git

This article originally appeared on earthli News and has been cross-posted here.

The helpful page, Ignoring files, taught me something I didn't know: there's a file you can use to ignore files in your local Git repository without changing anyone else's repository.

Just to recap, here are the ways to ignore a file:

  • Global .gitignore: you can designate basic exclusion directives that apply to all repositories on your system. This file is not committed to any repository or shared with others. Execute git config --global core.excludesfile ~/.gitignore_global to set the file to ~/.gitignore_global (for example). See the linked article for sample directives.
  • Per-repository global exclusions: add directives to the .git/info/exclude file in any repository. These directives are combined with any system-global directives to form the base exclusions for that repository. This file is not committed with the repository. This is the one I'd never heard of before.
  • .gitignore: add a file with this name to any directory. The directives in that file are merged with those from the parent directory to define the patterns that are excluded in that directory and all child directories. This is definitely the most common way to exclude files.
  • Exclude versioned files: and, finally, if your repository has files that are changed but not committed (e.g. configuration files), you can ignore future changes to those files with a call to git update-index --assume-unchanged path/to/file.txt. While this can be useful for legacy projects, it's best to structure new projects so developers don't have to rely on easily forgotten tricks like this.