The Minimum You Need to Know

About Qt and Databases

By Roland Hughes

Logikal Solutions

Copyright © 2010 by Roland Hughes
All rights reserved

ISBN­13

978­0­9823580­5­4

This book was published by Logikal Solutions for the author.  Neither Logikal Solutions
nor the author shall be held responsible for any damage, claim or expense incurred by a
user of this book as a result of its use or reliance upon.
These trademarks belong to the following companies:
Ask.com
IAC (InterActiveCorp)
Borland
Borland Software Corporation
DataBoss
Kedwell Software
Datatrieve
Hewlett­Packard Development Company, L.P.
DEC
Hewlett­Packard Development Company, L.P.
Firebird
General Motors Corporation when talking about cars
Firebird
Firebird Foundation Incorporated when speaking of database software 
Pontiac
General Motors Corporation
Interbase
Embarcadero Technologies.
Linux
Linus Torvalds
Lotus Approach International Business Machines Corp.
MySQL
MySQL AB
OpenVMS
Hewlett­Packard Development Company, L.P.
PostgreSQL
PostgreSQL Global Development Group
Quicken
Intuit Inc.
Qt
Nokia Corporation
SourceForge
Geeknet, Inc.
Ubuntu
Canonical Ltd.
Unix
The Open Group
Vista
Microsoft Corporation
Windows
Microsoft Corporation
All other trademarks inadvertently missing from this list are trademarks of their respective owners.   A best effort was
made to appropriately capitalize all trademarks that were known at the time of this writing.  Neither the publisher nor the
author can attest to the accuracy of this information.  Use of a term in this book should not be regarded as affecting the
validity of any trademark or service mark.

Acknowledgments
I'd like to thank my loyal base of readers and the incredible core team of Qt 
developers slaving away on an Open Source library that stands full torso above the 
commercial C++ cross platform libraries of old.

Source Code License
Any person owning a copy of this book may use the source code from this book
freely when developing software for their personal use, their company's use, or their
client's use.  Such persons may include the source code either modified or unmodified
provided that the source delivered makes reference to the original author and is part of a
fully functional application.   It is expressly forbidden for anyone to post this source
code on any bulletin board system, Internet Web site, or other electronic distribution
medium   other   than   SourceForge.net   without   the   express   written   permission   of   the
author.  It is also expressly forbidden to sell this source as part of a library or shareware
distribution of source.  All files for all projects presented in this book will be available
from http://www.theminimumyouneedtoknow.com 
Users of the source code contained within this book agree to hold harmless both the
author   and   the   publisher   for   any   errors,   omissions,   losses,   or   other   financial
consequences resulting from the use of said source.  The source code is supplied “as is”
with no warranty of any kind expressed or implied.

Table of Contents
Introduction......................................................................................................................1
1.1 Where We've Been and Where We Are Going.....................................................1
1.2 Not a GUI Tutorial................................................................................................5
1.3 Client­Server Full Circle.......................................................................................6
1.4 Today's Cross Platform Challenge........................................................................8
1.5 Why Ubuntu?........................................................................................................9
1.6 Why Qt?..............................................................................................................12
Table 1: Qt Database Drivers...............................................................................14
1.7 A Tale of Two Market Segments........................................................................17
1.8 The Mutant­Ninja Data Model............................................................................20
1.9 Exercises.............................................................................................................23
Cautionary Information..................................................................................................25
2.1 Scope of This Chapter.........................................................................................25
2.2 Development Restrictions...................................................................................25
2.3 Building a Qt Program........................................................................................26
2.4 The Database Username Restriction...................................................................27
2.5 Garbage Collection Restrictions..........................................................................31
2.6 More Database Issues..........................................................................................33
2.7 Pitfalls of Mandatory Passwords.........................................................................35
2.8 Database Frailty..................................................................................................37
2.9 Main.cpp for What?............................................................................................40
2.10 Transaction Integrity.........................................................................................42
2.11 SQL != SQL......................................................................................................49
2.12 Lassie Might Not Come Home..........................................................................52
2.13 Consistently Inconsistent...................................................................................54
2.14 Just Because You Found It, That Doesn't Mean It is There...............................57
2.15 To tr() Or Not to tr()?........................................................................................59
2.16 You Might be Optically Isolated.......................................................................64
2.17 What?  You Want to Create a Database?...........................................................66
2.18Exercises............................................................................................................67
PostgreSQL and Qt........................................................................................................69
3.1 Scope of This Chapter.........................................................................................69

3.2 Installing and Configuring PostgreSQL..............................................................78
3.3 Designer..............................................................................................................81
3.4 Inserting Into a PostgreSQL Table....................................................................109
3.5 Our Flow and Why............................................................................................114
3.6 qDebug or QMessageBox.................................................................................119
3.7 Error Handling for Remote Support..................................................................124
3.8 Plugin vs. Compile In Database Interfaces........................................................131
3.9 Logging On.......................................................................................................135
3.10 Hidden Signal and Slot Connections...............................................................151
3.11 Reading a Text File.........................................................................................152
3.12 Our Main Window..........................................................................................155
3.13 Reporting........................................................................................................177
3.14 The Boolean Issue Again................................................................................190
3.15 Browsing Database Records............................................................................192
3.16 Follow Up.......................................................................................................199
3.17 Backup Via CSV.............................................................................................200
3.18 Assignment One..............................................................................................207
3.19 Assignment Two.............................................................................................207
3.20 Assignment Three...........................................................................................208
3.21 Assignment Four.............................................................................................209
3.22 Assignment Five.............................................................................................209
3.23 Assignment Six...............................................................................................210
3.24 Assignment Seven...........................................................................................210
3.25 Assignment Eight............................................................................................210
3.26 Assignment Nine.............................................................................................210
3.27 Exercises.........................................................................................................211
Firebird and Qt.............................................................................................................215
4.1 Why Firebird?...................................................................................................215
4.2 Differences........................................................................................................218
4.3 Obtaining and Installing Firebird......................................................................219
4.4 Quirks Between Flavors....................................................................................224
4.5 Creating Users...................................................................................................225
4.6 Creating Databases............................................................................................226
4.7 Aliases...............................................................................................................230
4.8 No Boolean.......................................................................................................234

4.9 QIBASE Not Provided by Default....................................................................235
4.10 CSV Import and Export Part 1........................................................................242
4.11 Console Applications and IDEs.......................................................................247
4.12 #!/bin/sh..........................................................................................................258
4.13 Some Serious SQL Differences.......................................................................260
4.14 CSV Import and Export Part 2........................................................................266
4.15 xpnsfb..............................................................................................................300
4.16 Programming Assignment 1............................................................................328
4.17 Programming Assignment 2............................................................................328
4.18 Programming Assignment 3............................................................................328
4.19 Programming Assignment 4............................................................................329
4.20 Programming Assignment 5............................................................................329
4.21 Programming Assignment 6............................................................................329
4.22 Firebird Server Version Follow­up.................................................................329
4.23 Deploying This Contraption............................................................................331
4.24 Firebird Summary...........................................................................................334
4.25 Exercises.........................................................................................................335
SQLite and Qt..............................................................................................................339
5.1 Pros and Cons...................................................................................................339
5.2 Which SQLite?..................................................................................................346
5.3 Monkey Studio..................................................................................................347
5.4 Programming Assignment 1..............................................................................378
5.5 Programming Assignment 2..............................................................................378
5.6 Programming Assignment 3..............................................................................378
5.7 Programming Assignment 4..............................................................................379
5.8 Programming Assignment 5..............................................................................379
5.9 Our Application with Eclipse............................................................................379
5.10 Programming Assignment 4............................................................................415
5.11 Programming Assignment 5............................................................................415
5.12 Programming Assignment 6............................................................................416
5.13 Building Static vs. Plugin ...............................................................................416
5.14 SQLite Follow­up...........................................................................................417
5.15 Exercises.........................................................................................................419
Ruminations and Observations.....................................................................................421
6.1 CTRL­Y, CTRL­L, and ANSI...........................................................................421

6.2 Plugin vs. Static Compile..................................................................................424
6.3 What Database is Right for Your Application?.................................................427
6.4 Unstart...............................................................................................................431
6.5 Outages and Support.........................................................................................433
6.6 Ubuntu's Original Sin........................................................................................437
6.7 Qt's Achilles Heel..............................................................................................440
6.8 Package Maintainer vs. Marketing Fraud..........................................................441
6.9 Code What You Know......................................................................................443
6.10 Thursdays When It Rains................................................................................445
6.11 Bitflags............................................................................................................448

Chapter 1

Introduction

1.1 Where We've Been and Where We Are Going
Hopefully you've been reading along in this book series and are quickly progressing
as a developer or at least gaining a significant appreciation for what developers do.
While you do not need to have read the rest of the series, it might help.  The source code
for   the   PostgreSQL   expense   tracking   example   in   this   book   has   been   uploaded   to
SourceForge.net and can be found in the xpnsqt project.  All source files will be zipped
up and placed on  http://www.theminimumyouneedtoknow.com  for download as well.
Unlike most books in this series, there will not be an accompanying CD­ROM.
While I did not write the books in exactly this order, the correct order of reading
would have been:
The Minimum You Need to Know About Logic to Work in IT
ISBN­13 

978­0­9770866­2­7

The Minimum You Need to Know to Be an OpenVMS Application Developer
ISBN­13 

978­09770866­3­4

The Minimum You Need to Know About Java on OpenVMS
ISBN­13

978­0­9770866­1­0

The Minimum You Need to Know About Service Oriented Architecture
ISBN­13

978­0­9770866­7­2

The Minimum You Need to Know About Java and xBaseJ
ISBN­13

978­0­9823580­3­0

Infinite Exposure
ISBN­13

978­0­9770866­9­6

2

Chapter 1 ­ Introduction

Originally I wrote the OpenVMS Application Developer book to fill a need.  Lots of
places run OpenVMS and new installations are happening all of the time, yet there is no
source for new OpenVMS developers.  It wasn't until after that book was published that
I started getting feedback about recent college graduates not understanding logic.   At
that point I decided to make this a series and began writing the logic book.
With the logic and traditional application development books out in the field there
was   a   natural   progression.     First   we   covered   Java   on   OpenVMS   using   the   same
application   we   had   developed   in   COBOL,   BASIC,   FORTRAN,   C   and   C++   in   the
application book.  It was necessary to cover accessing of RMS files and RDB databases
via Java along with using FMS as your screen management tool.  Seasoned developers
wanted to learn some of the new technology and recent college grads only understood
new   technology   without   even   the   faintest   clue   about   how   to   access   the   data   which
actually ran the company.
Next   we   stepped   forward   with   Java   on   the   Ubuntu   platform   accessing   services
presented   by   OpenVMS   on   an   internal   company   network.     Some   of   you   might   be
shocked   to   learn   that   “The   Minimum   You   Need   to   Know   About   Service   Oriented
Architecture”   won   a   2008   Best   Book   Award   in   the   category   Business:
Computers/Technology/Internet  from  USA  Book News  and was  a 2009  Eric  Hoffer
Finalist.  There are a lot of books about Service Oriented Architecture on the market,
but damned few actually cover exposing the heritage data silos.  They usually try to sell
you a chunk of middleware and another never ending support contract along with shiny
new security holes.
The next book in the series didn't follow a logical progression per se, it came about
based   upon   need.     I   was   in   the   process   of   designing   and   writing   a   fuel   surcharge
application which would eventually be released as a Open Source project and should be
usable   by   someone   who   isn't   any   smarter   than   a   Microsoft   product.     That   last
requirement meant the application had to use its own indexed file system rather than
mandate a user install, configure, and become a DBA for some database product.  

Chapter 1 – Introduction

3

The XBASE family of file formats are the most widely used throughout the history
of PC computing, but the Java language doesn't directly include anything to support it,
nor does it include any other usable indexed file system.  (Yes, there is now a massive
development effort called Java DB, but not at the time I needed it.)  That meant I had to
learn a library.  I decided that if I had to take the time to learn a new library with scarce
documentation that I would write a tutorial and make life easier for the next guy.
Unlike the previous books in this series, the xBaseJ book is available in electronic
form only.  You can find the PDF with the files for the project on SourceForge.  You
can also find it listed here:
http://www.free­ebooks.net/ebook/The­Minimum­You­Need­to­Know­About­Java­and­
xBaseJ
From an educational perspective, I need to provide you with a book which uses a
popular   cross   platform   C++   GUI   tool   to   do   some   classic   standalone   development
against   a   database   server.     Many   in   the   world   of   IT   will   call   this   “Client­Server”
development   even   though   both   the   client   and   the   server   are   on   the   same   machine.
Historically, this type of development occurred prior to anyone even thinking about
inventing the Internet, but modern education wise, it is best to cover this topic  after
covering Service Oriented Architecture.
Why?  
Kids today know very little about application development, but they know a lot
about surfing the Web and buying things on­line.  It is easier for them to grasp a process
which involves some kind of Web page sending data to some back end system (Service
Oriented Architecture.)   Only a few of them will have had to work with Quicken or
some other personal finance/accounting application hosted on their own computer.   A
student who has actually used an application on a desktop computer which stores data
on a remote database without going through the Internet will be a rare find indeed.
“Infinite Exposure” is quite simply a novel which was written in response to an
interview question I got for the OpenVMS Application book.  While it has gotten some
great reviews, it is not part of my technical book writing.

4

Chapter 1 ­ Introduction

Some   of  the   previous  books   in   this  series  used  the  Mega   Zillionare  application
developed   over   and   over   again   so   you   could   learn   the   differences   and   trade­offs
associated with each tool choice.   I could bore the living Hell out of you doing that
again, but we don't have different tools, only different databases.  I'm going to have to
deviate from the norm and develop a new application for multiple databases to show
you the main issues.  Yes, Qt does quite a good job of hiding the database if you happen
to be using a relational database, but in most cases, you cannot simply change the
driver name­recompile­and­go.   There are quite a few differences between supported
databases.
Don't worry, I know  that most of you will be GUI only developers at best and
cannot   begin   to   function   without   the   continual   hand   holding   of   an   IDE   (Integrated
Development   Environment.)     While   I   developed   the   PostgreSQL   version   of   our
application with nothing more than a text editor and the Qt Designer for form layout,
our later examples will include using multiple IDEs and provide quite a few project
creation screen shots. You will be exposed to QtCreator, QDevelop, Monkey Studio,
and Eclipse with the Qt plugin.
Our   application   will   be   an   expense   tracking   system   which   initially   uses   the
PostgreSQL database.  We will then redevelop the application using Firebird (Borland
Interbase) and SQLite.  I will spend one chapter covering the use of stored procedures
in PostgreSQL and Firebird.  Our final technical chapter will cover problems with long
queries and threading.  It is too bad Oracle hasn't created a Qt plugin to access RDB or I
could   show  you   how   to   use   a  modern  desktop   with   the   world's   highest   availability
database.
We won't cover MySQL.  I know the database is popular.  I know many of you will
want to use it, but it's quite the quagmire right now.   By default, it is not a relational
database.  MyISAM is the default storage engine and is now the only storage engine for
the embedded version.  InnoDB was purchased by Oracle some time ago and Oracle has
started to squeeze that orange.
http://digitizor.com/2010/11/05/innodb­dropped­from­oracle­mysql­classic­edition/

Chapter 1 – Introduction

5

While InnoDB is still available in the “community” edition, the fact it has been
dropped from the Classic edition and InnoDB now has its own embedded/embeddable
version seems to indicate the “community” version of MySQL is going to be trapped
with a stagnant InnoDB release.
MyISAM creates a lot of data storage and application design problems.  It doesn't
currently   have   a   boolean   type   completely   implemented   and   there   is   no   support   for
foreign key constraints.  While the Boolean problem could be considered a nuisance, the
lack of foreign key constraints really torpedoes this project.  What good are reference
tables   containing   categories   and   expenses   if   the   database   isn't   going   to   enforce
referential integrity?   I went through this exact same problem eons ago when I used
XBASE files for each table.  Without an engine, I had to enforce the integrity from the
application level.  Not such a good thing.
1.2 Not a GUI Tutorial
This book will not be a GUI tutorial nor will it spend much time covering areas of
the Qt library which do not pertain to our sample application's database portions.  While
it is true that many developers could use this as a Qt tutorial along with the manuals
Trolltech provides on­line, that is not the goal of this book.
If you need additional information on the graphical portions of the library along
with the philosophy behind it all I can recommend is a pair of excellent books.
“Foundations of Qt Development”  ISBN­13: 978­1­59059­831­3
“C++ GUI Programming with Qt 4  Second Edition”  ISBN­13: 978­0­13­235416­5
In truth, this book is meant to cover the one area where those books really fell
down.  It's sad because it is the one area most developers actually need to understand.
Very   few   of   us   get   paid   to   write   painting   and   drawing   applications.     The   bulk   of
business development revolves around getting data into a database and getting reports
out of the database.

6

Chapter 1 ­ Introduction

1.3 Client­Server Full Circle.
The Web doesn't live up to its hype for most applications.  In many cases you want
control, security, and limited deployment.  In some cases you simply want a standalone
application   or   an   application   that   you   control   access   via   controlling   where   it   gets
installed.  You don't want information about your new super­secret billion dollar R&D
effort some place it could easily be poached.  You want that application secured on its
own internal network or machine without any connection to the Internet at all.
Standalone  programs  on  standalone  personal  computers  make  sharing  data  a bit
tough.  Without a network and exposing some portion of your disk storage to outsiders,
the options for sharing data are limited to physical media transfers along with dial­and­
deliver options.
Most   of   your   successful   standalone   development   happened   with   midrange   and
mainframe computers where hundreds to thousands of terminals were scattered about a
company, but they all connected into a single computer.  This made exposing the data as
simple as granting a user access to the files or databases.
During the late 1980s through the mid­1990s Client­Server was both the rage, and
the bane of computing.  Nobody was ever able to get it right, but everybody kept trying.
The real problem with client­server was application deployment.   We didn't have any
automated methods of “pushing” updates out to users and most users didn't have the
technical ability to perform an installation on their own.
When corporate desktops all ran some form of non­GUI DOS, file servers seemed
to  be  the  ultimate  solution.    Products  like  Netware  provided  security,  the  ability  to
address much more disk storage than most versions of DOS, and even provided an
indexed file system which handled multi­user access.  As long as the desktop computer
trying   to   run   the   application   didn't   have   too   much   of   that   precious   640K   already
consumed, they could run the executables a user could access.

Chapter 1 – Introduction

7

Users wanted more and more sophisticated applications.  Developers wanted to use
different tools which did more and more of the programming work for them.   These
tools had various licensing systems which invariably involved installing some kind of
encrypted license key file along with a run­time library (RTL) of some kind.  While the
file server could still be a great place to host the installation files and the actual data
created by the application, the days of having a single executable file which everybody
could run were pretty much over.
Another   drastic   thing   happened   near   the   end   of   the   1990s:   corporate   desktops
started to diversify.   While a great many people will be ignorant enough to say that
Microsoft rules the corporate desktop, they would be wrong.   Apple started making
some serious inroads due to things the platform could do which Microsoft simply could
not.  After the disastrous release of Windows Vista, many corporations started loading
various flavors of Linux on their company desktops as well as their servers.
Currently, the PC desktop industry is in a state of turmoil.  This turmoil will exist
for roughly another decade, but it will be good for the industry in general.  All but the
most hardened supporters of Microsoft have realized the company has a legacy platform
which is in the mode of continually shrinking market share.  Apple has a knack when it
comes to getting people to pay a premium for their stuff, and recently, per the stock
market, became bigger than Microsoft on a total_shares * share_price basis.  Another
player gaining a lot of momentum and respect are the various Linux distributions.  After
Windows Vista, anything looked stable, so companies gave it a try.  Then the economy
tanked world­wide.   Suddenly company heads started looking at the annual licensing
and support costs of Microsoft products and running the numbers against the Linux and
Open Source alternatives.  When the savings started being $20­$120 per employee per
year the 10,000+ employee companies started taking note and issuing marching orders.
The turmoil is what lead to the SOA (Service Oriented Architecture) stampede.
Some companies needed to get custom applications working on two to three versions of
Windows   as   well   as   the   current   Apple   OS   and   three   to   four   different   Linux
distributions.  Rather than fight the cross platform battle they lunged forward at the idea
of providing Web­based applications which used Java and other Open Source tools that

8

Chapter 1 ­ Introduction

ran in/on the major browsers for each operating system.
A great deal of effort was put forth by the W3C and many others to make SOA
work.     A   method   of   deploying   services   for   discovery   via   WSDL   (Web   Services
Description   Language)   was   created   so   any   application   anywhere   could   find   what   it
needed and simply pluginto the service.  The problem was much of this design centered
around openness, not privacy and security.  
It never ceases to amaze me when young MBAs refuse to write a new application
on OpenVMS or even an IBM mainframe.  PCs are all they have ever seen, therefore,
that must be all there is to use.  They are so dead set against creating a “green screen”
application which would be able to restrict access to only those who should really see,
that they bring us full circle, back to the mid­1980s and cross platform development.  
1.4 Today's Cross Platform Challenge.
In today's world, cross platform has a slightly different definition.   It used to just
mean different operating systems on the desktop, but now it extends to handheld devices
like   netbooks,   PDAs   (Personal   Digital   Assistant),   and   smart   phones.     In   truth,   the
distinction   between   cellular   phone,   PDA,   and   netbook   is   becoming   blurred   by   the
continual   addition   of   features   to   smart   phones   and   the   emergence   of   the   iPad.
Companies   are   making   wide   use   of   VPNs   (Virtual   Private   Networks)   on   handheld
devices so personnel in the field can run applications which access databases secured
behind the corporate firewall.  They have a need to maintain one application yet have it
run on every desktop, netbook, and PDA deployed by the company.  Let us not forget
you now have to deal with virtual keyboards and mice on most handheld devices.
I'm no stranger to cross platform development.   I was there when the first major
plunge happened.  Some of you might be old enough to remember the “Zinc It!” book
series.   It covered the Zinc Application Framework on DOS, OS/2, Windows, and to
some extent MAC.   The reason I know about that series is I was the author.   Zinc
Software was a poorly managed company. The product was purchased by Wind River
Systems and rolled into various products they offer.  Recently, perhaps because of this
trend, I have found Zinc is once again being sold as a product by a company.  I haven't
dug  too  deeply  into   it,  but  they   claim   to   support   desktop  and   embedded  platforms.

Chapter 1 – Introduction

9

There is also talk of an Open Source version as well.
Let's   be   honest.     While   some   commercial   product   vendors   will   use   the   cross
platform   capabilities   of   the   library,   many   in­house   developers   will   simply   use   the
library on a single platform with an eye toward being able to migrate quickly if whims
change.  A lot of companies which had been staunchly (and stupidly) in the Windows
desktop category are now starting to use Qt for Windows development.  They are in the
process of migrating everything to Qt so they can deploy Ubuntu, OpenSuSE, or some
other Linux distribution on the desktop as soon as the bean counters realize just how
much   it   costs   to   keep   Microsoft   around.     Microsoft   has   been   a   victim   of   its   own
marketing now.  When you actually total up all of the costs, it ends up being the most
expensive platform per user of any computing platform, including IBM mainframes and
OpenVMS midrange systems.  A lot of companies have learned that the OpenVMS box
which is still housing their data and some core applications is/was the cheapest per user
solution they had even if they didn't like green screen applications.
1.5 Why Ubuntu?
If   you   have   already   read   “The   Minimum   You   Need   to   Know   About   Service
Oriented Architecture”, then you aren't asking the above question.   For those of you
who skipped that book in the series, Ubuntu is quickly becoming the desktop Linux
distribution of choice for most IT professionals and even quite a few corporations.  Dell
has even started pre­loading Ubuntu on machines for corporate customers.  Yes, Lenovo
is pre­loading OpenSuSE, but most other vendors are embracing Ubuntu.   OpenSuSE
has been tainted by a business deal between Novell and Microsoft which infuriated most
of the various Unix/Linux factions and spawned a re­write of the GPL (GNU Public
License) which put Novell in a world of hurt.
We won't get too deep into arguments about which is technically better.  I have used
both in the past.  I used to actually pay for the professional edition of SuSE before it got
the silent “Open” added to the front of it.   All code in this book will be written and
tested on version 10.10 AMD 64­bit KUbuntu.  You should be able to adapt things for
your own environment.  I can warn you that many versions of OpenSuSE made it nearly
impossible to get PostgreSQL running.  It would eventually run, but you had to scour

10

Chapter 1 ­ Introduction

the Internet looking for hints, snippets, and advice.  Ubuntu made it an easy install and
nearly automatic configuration.   If you are a developer that doesn't want to be a Sys
Admin and you don't like hacking kernel startup scripts, Ubuntu is the simpler choice.
Developers who want lots of development tools included with the initial installation
tend to prefer using OpenSuSE.   Corporations and their support staff tend to prefer
Ubuntu.   In either case, you don't notice a lot of difference unless you are willing to
open   up   a   terminal   window   and   start   keying   in   commands,   or   you   need   to   install
something different.  Ubuntu uses the Synaptic Package Manager for installations while
OpenSuSE   uses   YAST   (Yet   Another   Setup   Tool)   for   everything,   including   adding
users, changing the system time, etc.   You can load KDE or Gnome front ends under
either distribution.
Corporations   are   preferring   Ubuntu   desktop   distributions   because   the   default
desktop interface is based on Gnome.  This is a clean, minimalist interface.  Users who
don't understand the inner workings of Linux will find themselves somewhat limited to
surfing the Web, creating documents, checking email, and whatever application links
were   pre­loaded   by   the   corporation.     To   get   both   the   KDE   and   Gnome   session
interfaces, you need to navigate your way to the package manager after installation and
install the KDE interface (KUBUNTU).  KDE is a much more functional interface than
Gnome.  I will admit there are certain specific things which are much easier in Gnome
than KDE, but most common things are far easier in KDE than Gnome.   If you have
both interfaces installed, you can simply log out and log back in changing your session
to which ever interface is easier for what you need to do.  
If you install both interfaces on Ubuntu though be prepared for a lot of things to
either   not   work   or   work   spastically.     The   Ubuntu   crowd   tests   only   one   installed
interface with each release.  I have tried many times to make both KUbuntu and Ubuntu
play nice together, and finally gave up.  Every time you try to log a support issue you
get told to wipe everything and install just Ubuntu.
Corporations are more than happy to stick their users with the Gnome interface
because they want to restrict what people do on their desktop.  How many billions have
been lost to people installing stuff on their Windows desktop only to find out it had a
virus or some other nasty security hole?  A restricted interface keeps users from poking

Chapter 1 – Introduction

11

around   and   installing   stuff.     The   user   account   can   also   be   set   up   to   not   allow
installations.
The other major selling point for Ubuntu is stability.  Yes, many flavors of Linux
and other PC­based operating systems claim stability, but when you ask them how they
achieve it, you get a lot of buzzwords along with a song and dance.  Ubuntu is generally
a year behind the bleeding edge found in the source trunks.   While they will pull in
some patches and fixes which are newer, they are generally at least six months behind
the last stable release of any package which tends to be four to six months behind the
bleeding edge of the development trunk.  The core developers for Ubuntu will tell you
they release every six months so they are only six months behind.  This is true only if
you are measuring from the last “stable” release each package developer turned out.
OpenSuSE releases once every eight months.   They don't put out an LTS release,
but   they   don't   have   a   spastic   numbering   system   like   Ubuntu.     OpenSuSE   11   has   a
roadmap spanning several years and multiple .x releases.   Ubuntu releases during the
fourth and tenth month of every year.  Their versions are number YEAR.MONTH.
In short, we are using Ubuntu because it plays the game the best and doesn't have a
taint from the Microsoft­Novell deal and doesn't have YAST.   That said, Ubuntu has
about a five year window to fix what is wrong with it before it disappears from the
market place like Corel Linux.  For more information on that read, “Ubuntu's Original
Sin” in the Ruminations chapter.

12

Chapter 1 ­ Introduction

1.6 Why Qt?
To start with, there is an Open Source version which is regularly updated.  It is the
GUI library used for all KDE project development.  Linux is gaining a lot of popularity
and KDE is the major desktop.  While Gnome gained a lot of corporate support because
it is a bare interface which doesn't let the experimental end user get into too much
trouble, for most developers and seasoned computer users, Gnome is much like rubbing
sticks together to make fire.
While it can be correctly stated that Open Source projects let in far too many junior
programmers with buggy code, that statement would be incorrect when it comes to the
Qt library.  There are commercial developers sifting the wheat from the chaff.  This is
not to say the library doesn't have bugs.   What I'm  saying is that there are literally
thousands of developers working on various portions of KDE (and now the new Ubuntu
Gnome­like interface based on Qt instead of Gtk+.)   These developers report bugs as
they find them and in many cases send along source changes to be incorporated into the
main product trunk.   Few commercial products can afford thousands of professional
developers.   By going Open Source with much of the library, Trolltech (now part of
Nokia) has affectively added thousands of developers to their staff at little to no cost.
The cross platform libraries from days of old didn't go this route.  They tried to get by
with a limited number of in­house developers funded by astronomical license fees.
Let us not forget that Nokia has chosen Qt as its standard (basically by purchasing
the product) and there is a lot of development going on for handheld applications in that
company.   More and more embedded systems developers are choosing to use Qt on
their   embedded   project   as   a   result   of   this.     Ubuntu   even   announced   that   the   main
development library for its Gnome­like front end will now be Qt as well.  While there
are many Gtk+ diehards out there, the writing is on the wall.  Qt managed to achieve a
consensus of what should be provided on all platforms and the “benefits” of proprietary
toolkits no longer exceed the “costs” of using them.

Chapter 1 – Introduction

13

There is a lot of on­line documentation on Qt.   Trolltech and Nokia have gone to
great lengths to make all of Qt's documentation available on­line.  Many other sites also
host copies of it in case the primary site goes down.  In addition, the documentation is
included   in   the   free   QtAssistant   document   browser   which   is   installed   with   most
development packages.  Much of the documentation is “expert friendly.”  It works well
if you are already a seasoned veteran and just need to look something up.   It doesn't
work well from the learning aspect.
I needed to develop the xpnsqt application to replace something I had written in
Lotus Approach many years ago.  I kept waiting and waiting for Lotus/IBM to have a
divine visitation and port the Lotus SmartSuite to Linux.  I guess all of the major deities
have been busy for the past decade.   Now that OpenOffice has made great strides the
word processor and spreadsheet market simply wouldn't be profitable.   Approach was
one of those tools nobody used much.  It did things well so you simply didn't remember
what tool you used for development.   The xpnsqt application took me 45 minutes to
develop   with   Lotus   Approach   well   over   a   decade   ago   without   ever   having   used
Approach before.   The replacement weighed in around four days.   Two and a half of
those days were spent trying to use a new Qt database class one of the books was gaga
about.  That class simply wasn't ready to run with the big dogs.
You have quite a few database choices when developing with Qt.   The database
classes are actually wrapper classes for various database plugins.  Many of the plugins
can be compiled into the library so they are statically linked with your application.
Static linking provides an immense amount of data and application security over plugin
use.  For more on that topic see “plugin vs. Static Compile” in the Ruminations chapter.
At the time of this writing Qt supports the following database plugins:

14

Chapter 1 ­ Introduction

Driver

Database

QDB2

IBM DB2 version 7.1 and later

QIBASE

Borland InterBase

QMYSQL

MySQL

QOCI

ORACLE (Oracle Call Interface)

QODBC

ODBC (includes Microsoft SQL Server)

QPSQL

PostgreSQL 7.3 and later

QSQLITE

SQLite version 3

QSQLITE2

SQLite version 2

QTDS

Sybase Adaptive Server

Table 1: Qt Database Drivers

Not all drivers are shipped with all versions of Qt.   Some drivers only work on
some   platforms   because   the   database   only   runs   on   some   platforms.     Other   than   an
ODBC   driver,   I   don't   know   how   you   would   access   Oracle   RDB   from   within   Qt.
(Remember   that   Oracle   and   Oracle   RDB   are   two   completely   different   database
products.)  Interestingly enough, the OpenVMS community has been porting Qt to the
OpenVMS platform for quite some time.  Trolltech doesn't seem willing to adopt these
ports,   so  the  community   has   been  working  diligently   at   them.    You   can  find   some
interesting information in this message thread:
http://groups.google.com/group/comp.os.vms/browse_thread/thread/4e1bacfc0f33584c/
00c4ad8634cf9f0e?hl=en&lnk=gst&q=Qt#00c4ad8634cf9f0e

Chapter 1 – Introduction

15

Qt comes (on most platforms) with its own version of SQLite.   This is like the
default   MySQL   for   many   Linux   distributions,   without   the   additional   administration
issues.     It   is   an   SQL   interface   wrapped   around   an   indexed   file   system.     (MySQL
defaults   to   an   indexed   file   system   on   most   platforms.     You   have   to   actually   force
InnoDB at time of database creation to get a relational engine.)  Since SQLite is much
lighter than MySQL, it will let you create your indexed files pretty much where ever
you happen to be.  MySQL requires databases to be created where its startup script or
system logical points (at least for the server version.)   It is popular with PC­minded
developers because it allows them  to gain the benefits of an SQL  interface without
having to learn how to actually design and develop around a database.  (Those of you
looking for more information about logicals should read ISBN­13 978­0­9770866­3­4.)
In theory, the wrapper classes protect you from the quirks found in each database.  I
say in theory because the higher level wrappers don't work cleanly yet, so you end up
writing quite a bit of SQL and using query functions.   Each target database has some
minor differences in their query languages and connection methods.   Why hasn't this
become a major issue?   Quite simply, very few applications ever get ported between
database products.  The primary development effort with Qt has been to use it writing
KDE (the K Desktop Environment for Unix/Linux), many text editors, and a few IDEs.
A major secondary market has been to develop applications for Nokia phones and other
handheld devices.  Very few applications are ported between the two environments, but
that is starting to change.  Most of those which are ported can get by with the limited
capabilities of SQLite.
These   days,   many   companies   will   start   development   with   a   cross   platform   tool
knowing they will have to port to another platform in the future, even if they don't want
to port.  How is that possible?  Take a look at the DOS market.  There were a rash of
DOS specific GUI libraries during DOS's heyday.   Then came Windows (GUI DOS),
Windows   for   Work   Groups   (even   more   GUI   DOS),   Windows   3.x   (still   more   GUI
DOS), Windows 95 (GUIer DOS), Windows 98 (DOS locked in the dungeon still doing
the  bulk  of  the  work  for  the  GUI), Windows NT,  Windows  XP, and  most  recently
Windows Vista.  (Yes, I skipped OS/2, a better DOS than DOS and a better Windows
than Windows.)  Every three to ten years, the underlying environment changed.  A cross
platform library can minimize the impact to your application.   In a best case scenario

16

Chapter 1 ­ Introduction

you simply have to recompile and create a new installation procedure.
When Zinc came out, it straddled the DOS, OS/2, Mac, and Windows markets.  The
underlying problems with the product all stemmed from not having an Open Source
version.  The vendor was left trying to develop and support a rash of moving targets,
and   was   always   hampered   by   the   limited   address   space   of   the   DOS   environment
combined with near zero free DOS extenders.  By the time some of the better quality
DOS extender tools became “free” or cheaply licensed, the market had moved.  During
the   first   round   of   cross   platform   libraries   we   also   had   a   large   number   of   compiler
vendors combined with evolving standards for both C and C++.  Today there are very
few compiler vendors and the standards have settled.  While there still are commercial
C++ compilers out there, most developers are migrating to the Open Source compilers
of   either   GNU   or   Watcom   (which   oddly   enough   used   to   be   the   highest   quality
commercial compiler back in the day.  OpenWatcom now has a Linux version besides
all   of   the   other   versions   it   used   to   have.
http://www.openwatcom.org/index.php/Main_Page )
How many of you have been around long enough to remember the pain of porting
from Windows 3.x to Windows 95 to Windows 98 and the later ports?   If you didn't
have a wrapper library things were ugly.   Because Vista took so long to get into the
market, people forgot and started using a lot of native tools when developing on XP.
The release of Vista taught another generation of developers the sad lesson of using
platform and vendor specific tool sets.  The much (and rightfully) maligned Vista also
opened the door for Linux distributions on the desktop.   People decided they weren't
going to go through this yet again simply to stay current.
The other benefit of using a tool set which runs on many different operating systems
(notice I avoided saying cross platform) is that your pool of potential developers gets
much   wider.     Yes,   many   are   contributing   things   to   the   Qt   library   itself,   but   what
happens when you need to hire new developers?  Most companies have learned the pain
of using proprietary systems like Windows and Microsoft specific tool sets.  Colleges
quit teaching things that aren't free when they are strapped for cash.   Your pool of
possible   employees   shrinks   every   semester   once   that   trend   starts.     Vendors   keep
increasing the pricing of their tools so the only way you can get new talent is to steal

Chapter 1 – Introduction

17

someone else's old talent.  A lone wolf simply isn't going to plunk down thousands of
dollars to obtain all of the tools in the “hope” they will land a good paying contract.
I have seen job openings posted for months listing six to twelve vendor specific
tools.     When   the   posting   stays   open   in   excess   of   a   year   they   claim   there   is   an   IT
shortage.  There is no shortage.  They were simply posting a job opening looking to pay
$60,000/year for a skill set commanding $120/hour.  Had they been willing to pay the
actual   market  rate,  they  would   have   gotten  the  talent  they  wanted.    Had  they  been
willing to hire a programmer who had none of those skills, but was willing and able to
learn, they would have gotten somebody for the money they offered.
A   lot   of   companies   are   moving   to   Qt   to   avoid   being   trapped   by   a   proprietary
platform like Windows and its proprietary tool sets.  If a developer already knows how
to develop with Qt, they only have to learn a few of the quirks and the editors on the
new platform.  This is, of course, making the assumption you have managed to migrate
all of your data into relational databases which have plugins/compile­ins available.
1.7 A Tale of Two Market Segments
What   is  really   the  fundamental   difference  between  the  Mac   market   and  the  PC
market?  Apple has completely tossed out prior architecture on more than one occasion,
yet Apple is now the leading college campus computer manufacturer.   Vista required
such a massive hardware upgrade for most existing Windows users that the industry
refused   to   upgrade.     After   officially   dropping   support   for   Windows   XP,   Microsoft
began selling a “Business Edition” Vista license.   I set up one of these computers for
someone.  Do you want to know what the “Business Edition” really is?  It comes with
bootable media which will wipe Vista off your machine and install Windows XP Pro.
Microsoft counts this as a Vista license sale, but they really just sold another copy of
Windows XP Pro.  Oh, let's not forget about when the netbooks came out!  They didn't
have enough resources for Vista, so Microsoft began selling XP on them again.   So
much for the sunsetting of XP.

18

Chapter 1 ­ Introduction

How is it that the Apple customers are willing to endure this, but the Microsoft
customers are not?  When Apple throws out the prior technology, they throw it out lock­
stock­and­barrel.  A major improvement in both the operating system and the hardware
shipping with it occurs.  There is a compelling reason to ditch the old stuff for the new
because it always feels like you are upgrading from a Model T to a fully loaded Caprice
Classic.   Apple also targets a niche.   Apple does not market itself as a general office
supply like a stapler or a handheld calculator.
Vista   was   not   a   major   improvement.     Microsoft   doesn't   control   the   computer
hardware like Apple does.  Anyone who has seen any of the “I'm a Mac and I'm a PC”
commercials where the PC user was rejoicing about being error free for nearly a week
can get a good understanding of just how bad Vista has been.   So bad, Microsoft has
come up with a new campaign where they won't even use the name Vista anymore.  Too
bad for them the eBook version of this book will remain for sale on servers long after
Microsoft has ceased to exist.
Over  the  course  of  its   existence,   Microsoft   had  managed   to   compel  people   and
companies to upgrade and stay current with the latest toys.  That worked until the PC
became a standard office supply.  Companies look to spend as little as possible when it
comes to standard office supplies.  If any of you have tried to get a name brand surge
protector because of some delicate equipment through your local office supply group,
you know what I mean.   What they ship you is a $2 generic that may or may not
suppress anything.  
Windows XP Pro became successful because it remained virtually unchanged for
six years.  Companies developed a lot of software for it, and most employees already
had some idea of how to check email and surf the Web on it when they were hired.  It is
a   heritage   system.     The   very   thing   Microsoft   (and   most   everybody   trying   to   sell
something new into IT) rails against, claiming it is holding people and companies back
from reaching their full potential.   What the marketing types don't understand is why
heritage systems exist:

Chapter 1 – Introduction

19

1. They are a sunk cost.  
2. They do their job.
3. Most companies don't make money changing software or hardware platforms.
Apple can get away with a complete redesign of their platform because the office
desks they are found on need/want all of the improvements the new platform provides.
They occupy creative niches at companies and really are still personal machines.  The
PC targeted the much wider “business tool” market.  What Microsoft shareholders and
leaders haven't realized yet is that once a bean counter is in charge of buying hammers
for the carpenters, the carpenters will all be carrying the cheapest hammer out there.
When Apple moved to Intel­based chips it opened the door for going head to head with
Microsoft and some companies warmed to the product line.  It should also be noted that
Apple   recently   exceeded   Microsoft   in   market   cap   size   per   the   SEC   formula   of
share_price * authorized_shares.   This isn't because Apple is taking over the business
desktop,   rather   it   is   because   Microsoft   is   losing   the   business   desktop   to   Linux,   the
cheapest hammer out there.
Vista made Apple look like a better deal in the eyes of many bean counters as well.
Vista   required   significant   hardware   upgrades   and   was   deservedly   maligned   in   the
industry trade press.  When the bean counters started adding up the upgrade costs and
totaling in the cost of Vista problem resolution along with lost business productivity the
higher priced Apple products started looking cheaper by the minute; of course Linux,
with its free office software suite which could run on the existing desktops without any
hardware upgrades looked the best of all, but that required a bit more selling.

20

Chapter 1 ­ Introduction

1.8 The Mutant­Ninja Data Model
Many of you might be long enough in the tooth to remember when you couldn't
pick   up   a   weekly   geek   magazine   without   seeing   a   bunch   of   ads   and   reading   more
articles about how object databases were going to completely replace all other database
engines.  Well, that didn't happen, but the industry did get hungry for some capabilities
which only object databases could deliver.  Likewise, hierarchical databases fell out of
favor, but never disappeared.  We are now beginning to see what some geeks will call
the Mutant­Ninja database model, but others will call the object­relational­embedded­
hierarchical   model.     Some   even   try   to   leave   out   the   fact   there   is   an   embedded
hierarchical database by simply calling it the object­relational model.  I prefer to call it
the Mutant­Ninja Data Model.
There aren't really any of these for us to play with in the Open Source world.  For
some strange reason the only people working on them  are the commercial database
providers.  Given the nature of the Open Source world it would be a lot smarter to come
up   with   a   design   in   the   commercial   world,   then   Open   Source   it   to   shake   out   the
problems.
For a while we had some database engines using relational as the outer engine,
accessing blobs via an object model of some kind, and still providing hashed index file
services.   DBAs, to a large extent, hand pick each storage type, database model, and
location.  We are less than ten years away from that changing on a permanent basis.
In a not too distant future, a DBA will run an interactive tool when they want to
create a database.   It will ask them some questions about initial row counts, column
names and data types, foreign keys, and key/index columns needed.   The DBA will
choose existing tablespace, or be allowed to create shiny new tablespace, then, when all
questions have been answered, the tool will create a database in the format it chooses
keeping hidden all knowledge of its real organization.  We will no longer use a database
model, but a Data Storage System that will determine all of the “how” yet promise us
we can view the information as we wish as long as we access it via the URL it provides.

Chapter 1 – Introduction

21

There is nothing which can be done about this.  It is the only logical progression.
Each database model has a class of problem it is uniquely perfect at solving.  XML is
used   nearly   universally   for   external   communications   and   companies   are   seeking
methods   of   storing   this   beast.     An   XML   document   is,   by   definition,   a   hierarchical
document.   When you have a limited number of rows in a reference table, nothing is
faster than a sorted sequential file and a binary search, unless the data is really short,
then linear search.  The “almost small” row count data set lends itself to a hash table,
but “almost small” tends to be defined by the quality of the available hash.  When you
have   a   medium­sized   data   set   with   less   than   four   segmented   keys,   VSAM   (RMS
Indexed)   rules.     When   you   have   real   time   data   coming   in   that   requires   embedded
triggers to automatically fire once certain methods return true, object makes it a piece of
cake.  When you have tables with massive amounts of data requiring serious amounts of
referential integrity, relational is currently the answer.
We have spent the last 20 years migrating perfectly good business systems to
relational database systems for no other reason than to get SQL access.  
While   it   is   true   that   some   of   those   systems   had   their   lifespan   greatly   extended
because the relational model didn't have the same file size limitations their previous
storage models had, it is also true that we had 4GL tools the industry chose to shit upon.
One of the most impressive 4GL tools I ever worked with was Cognos PowerHouse.  It
ran on many platforms and you could link a native indexed file to an RDB database to
an Oracle database to a Sybase database to N other databases all in the same report,
batch update module, or data entry screen.  The tool is still available today, but Cognos
is now owned by IBM.  You really should try it before your IT career ends.
What happened was the industry went through a period where proprietary things
were considered bad (yet for some odd reason proprietary database systems like Oracle
and DB2 were considered good.)   The only reason for it at the time was the fact the
Gartner Group was paid to market “Open” systems.   The definition of “Open” was
“whatever they were paid to sell this week” because somehow Microsoft, one of the
most proprietary operating systems on the face of the planet having a single vendor and
damned little accurate kernel documentation, was also branded as “Open.”

22

Chapter 1 ­ Introduction

The end result of this disaster was an MBA mindset that you couldn't pay a support
contract for a cross platform 4GL, but you could pay one for a proprietary relational
database because SQL was an “open” standard, never mind that every database had its
own dialect of SQL and that very little production code could ever migrate.  Since the
MBAs wanted to be able to access all information the company had via an “oooh look at
the   colors”   dashboard   application,   all   data   had   to   be   in   the   relational   database   that
dashboard used.
Now you find many SQL front end tools and libraries for old data storage formats.
It wasn't until recently that upper management learned the SQL wrapper provided by
MySQL really worked with an indexed file system rather than a relational database by
default on most platforms.  Most didn't know that until Oracle bought InnoDB, which
was the relational engine shipping with MySQL and a public brew­ha­ha ensued in the
trade press.
Long   hours   combined   with  massive   quantities  of  caffeine  and  nicotine  are  now
happening behind closed doors at all of the major database vendors, and probably some
of the Open Source projects.  Of course they will have to come up with a sexier name
than DSS (didn't IBM call some ancient form of DASD DSS?) and they cannot use
DataWarehouse   because   that's   already   been   used   for   other   things,   but   the   solution,
however named, will be the same.   The DBA will use a tool which lets them specify
how the columns will be viewed by the outside world, but the database engine will
choose  how   to  store  them.    More  importantly,  it  will  dynamically  switch  from  one
format to another when it senses a limit being reached and automatically rebuild indexes
when   it   notices   performance   degradation.     We   will   no   longer   have   any   low   level
recovery options.   We will use the backup and recovery tools provided by the system
and the people who created SOX will be happy because now we have only one tool for
data storage and their audits will be easy.
Of course, some of you might think this is sounding all too familiar.  Well, it is, if
you happen to ever work with the PICK operating system.
http://en.wikipedia.org/wiki/Pick_operating_system

Chapter 1 – Introduction

23

We will have a different database engine, but we will be headed back there shortly.
What do you want to bet we end up with a mish­mash of BASIC  and SQL as the
primary languages again?
1.9 Exercises
1. Why do heritage systems exist (3 reasons)?
2. What does WSDL stand for?
3. Without a network and without the ability to expose part of your disk farm to
outsiders, how do you have to share data?
4. What  are  the three main  reasons which would  force  a client­server  solution
instead of a Web based solution?
5. What was the really big problem with client­server computing during the 1980s
through the mid­1990s.
6. What does YAST stand for?

24

Chapter 1 ­ Introduction

Page left blank intentionally.

Chapter 2

Cautionary Information
2.1 Scope of This Chapter
In this chapter we will cover some of the major issues encountered when using Qt
and/or databases.   These will be the kind of things which “shouldn't” happen.   When
they do happen you chase your tail for hours and sometimes days tracking the problem
down.
2.2 Development Restrictions
If   you   come   from   a   development   environment   on   a   robust   platform   which   was
centered around a code management library, developing with the Qt tool set is going to
seem like an act of extreme sacrilege.  The Unix, and by extension Linux, platforms do
not have any concepts of logical names or distributed architectures.  Here, you have at
best, a PC mindset.   That mindset, being small, simple, and not looking further ahead
than the weekend, developed a tool set which matched its thought patterns.   There is
only one guiding principle.
Everything in a single directory tree.
You   will   find   this   philosophy   wrapped   up   in   every   Open   Source   project   you
download or use.  Back in the days when we only had indexed files we could muddle
through.    When  you  start  actually  running  software  as  an  installed  image  and  need
multiple versions, this philosophy starts to break down.   It goes completely out the
window   when   you   need   to   run   D,T,S,   and   P   versions   of   databases.   (Development,
integration  Testing, production  Support, and  Production, all on the same machine or
cluster.   Generally running Production on your development machine(s) is part of a
disaster recovery plan.)   I covered the bulk of the DTSP issues in ISBN­13: 978­0­
9770866­0­3, please refer to it for further information.

26

Chapter 2 – Cautionary Information

2.3 Building a Qt Program
Once you have all of your source files in a single directory, you need to create a Qt
project file.   If Qt has been correctly installed on your machine, you can do this by
simply typing:
1)
2)
3)

qmake -project

A file using the current directory name with a .pro extension will be generated.
The name of the executable file which comes out of the entire build process will also be
the same as the directory.   (I think you are now starting to see why I harped on the
“Everything   in   a   single   directory   tree”   philosophy.)     It   was   never   a   good   idea   on
midrange platforms to have a directory provide the name for an executable contained
within the directory, and it was an even worse idea on the mainframe platform, but hey,
the   Open   Source   community   is   all   gaga   over   using   a   convention   which   has   failed
miserably on every other platform.
When dealing with a relational database via the Qt libraries, you need to manually
edit the resulting PRO file to add the following highlighted line prior to generating the
Makefile.
4)
5)
6)
7)
8)
9)
10)
11)
12)
13)
14)

######################################################################
# Automatically generated by qmake (2.01a) Sun Jun 6 19:10:04 2010
######################################################################
TEMPLATE = app
TARGET =
DEPENDPATH += .
INCLUDEPATH += .
QT += sql
# Input

I don't know why the qmake tool isn't smart enough to do a quick scan inside of the
files and determine an application uses the SQL classes.  Once you've added the line and
saved the file you can run qmake one more time without any parameters to generate a
Makefile.   Your final act of building an executable is to type make and watch it run.
Assuming   you   don't   have   any   typos   or   other   compilation   errors,   you   will   get   an
executable with the same name as your directory.

Chapter 2 – Cautionary Information

27

Because this section of the book is about development restrictions, take a look at the
other   lines   above   our   highlighted   line.     The   “.”   stands   for   the   current   directory.
Everything   is   assumed   to   be   in   your   current   directory.     If   you   want   to   change   the
resulting executable name you must provide a value to the TARGET line.  When you
are   using   third   party   libraries   and   need   to   force   recompilation   due   to   a  header   file
changing, you need to add the directory tree holding the header files to DEPENDPATH.
To ensure the compiler looks in that third party directory for header files, you need to
also add it to the INCLUDEPATH.  Use a space or a “;” to separate entries in the path
list.  There is a long list of variables which can be defined in this file.  Use your favorite
Web search engine (hopefully not Google) and search for “Qt includepath” without the
quotes.   You  should see at least one link to a Nokia/Trolltech documentation page.
Hopefully the documentation page has a version number close to the version you are
using of Qt so everything works the way it is described.
2.4 The Database Username Restriction
One of the most frustrating aspects you will encounter is obtaining the username
and password  for database access.   It sounds simple.   Using a procedural tool, you
would pop up a window to prompt for these, then delete that window and display your
main form or forms.  Even with our Java applet in “The Minimum You Need to Know
About Service Oriented Architecture” we handled this cleanly.  Not so when it comes to
designing your Qt­based applications.  Handling this one task dramatically impacts your
application design.   Most examples you will find for Qt concentrate only on the GUI
aspect since it was originally a GUI library.  Each will have a main.cpp file which looks
much like the following.
1)
2)
3)
4)
5)
6)
7)
8)
9)
10)
11)

#include <QApplication>
#include "mydialog.h"
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
MyDialog *dialog = new MyDialog;
dialog->show();
return app.exec();
}

28

Chapter 2 – Cautionary Information

When the initial GUI object is a dialog you typically allocate it by calling  new and
let the Qt environment delete the attached object when the application exits.  What you
have to remember is that Qt programs aren't just GUI OOP programs, they are event
driven.  Everything occurs in the event loop handled by the QApplication object method
exec().  I've been through this many times with other products.  I'm very glad I am not
covering device IO in this book like I did in my first Zinc book.   When you end up
handling IO from 32+ port serial cards and controlling relays via digital IO and Opto­22
components you end up having to code your own event loop to handle such things.
Adding a database to this mix opens nearly the same can of worms, not because you
have to hack your own event loop, but because in the Qt world the database object is
global data.   It really needs to be owned by the main.cpp file so it never goes out of
scope and isn't garbage collected on you.  Keep in mind what I told you about C++ in
“The Minimum You Need to Know to Be an OpenVMS Application Developer”: Once
an   object   goes   out   of   scope   it   is   eligible   for   garbage   collection.     Some   compilers
garbage collect immediately and others postpone the collection until idle time.   Java
developers will have an easier time understanding this given that Java almost always
waits until idle time to perform garbage collection.
Your   second   major   problem   with   adding   a   database   to   the   mix   is   the   method
different databases use to validate a user.   Some relational engines are configured so
that any user on the local machine has automatic validation, other relational databases
provide their own user authentication.  Some databases use both methods.  The first for
local users and the second for users accessing via TCP/IP services.
Many   of   you   are   probably   having   trouble   understanding   what   I'm   complaining
about, so let me give you a small example.   Here is the main.cpp from  the xpnsqt
project.

Chapter 2 – Cautionary Information
1)
2)
3)
4)
5)
6)
7)
8)
9)
10)
11)
12)
13)
14)
15)
16)
17)
18)
19)
20)
21)
22)
23)
24)
25)
26)
27)
28)
29)
30)
31)
32)
33)
34)
35)
36)
37)

29

/****************************************************************************
* Originally created by Roland Hughes at Logikal Solutions.
* Project is being released under GPL2 license.
*
* At some point in the future either Logikal Solutions or Roland Hughes
* may elect to publish a book with this original source code in it. If
* the book is written it will be part of "The Minimum You Need to Know"
* book series.
****************************************************************************/
#include <QtGui>
#include <QtSql>
#include <QtDebug>
#include "XpnsLogonDialog.h"
int main(int argc, char *argv[])
{
int i_x;
QString qtDbName;
QTime theTime = QTime::currentTime();
QApplication app(argc, argv);
{
QString driverName = "QPSQL";

//
// Set up information for driver and see if driver is available
//
qtDbName = "xpns" + theTime.toString("hhmmsszzz");
QSqlDatabase db = QSqlDatabase::addDatabase(driverName, qtDbName);
if (!QSqlDatabase::isDriverAvailable( driverName)) {
QMessageBox::critical( 0, "Missing PostgreSQL Driver",
"The Qt driver for PostgreSQL "
+ driverName
+ " is not installed. You must install it before running
this program",
38)
QMessageBox::Ok);
39)
db = QSqlDatabase();
// reset to avoid warning
40)
return 0;
41)
}
42)
43)
XpnsLogonDialog *xpnsLogonDialog = new XpnsLogonDialog( 0, qtDbName);
44)
xpnsLogonDialog->show();
45)
i_x = app.exec();
46)
qDebug() << "About to delete dialog";
47)
delete xpnsLogonDialog;
48)
qDebug() << "Dialog deleted, now clearing database";
49)
50)
db = QSqlDatabase::database(); // clear connection to avoid error
51)
} // end scope of logon dialog
52)
53)
QSqlDatabase::removeDatabase(qtDbName);

30
54)
55)

Chapter 2 – Cautionary Information
return i_x;}

Pay special attention to the highlighted {} surrounding the inner code in this module
(listing lines 25 through 51.)  This is required to ensure the db object goes out of scope
and is garbage collected.  Just prior to exiting that block I have to assign the db object to
the default database.  You can only remove a database from the global storage area once
all references to it have been removed.
The global QSqlDatabase object creates a “default” database object whenever you
include   SQL   support   in   your   program.     Many   developers   will   only   use   the   default
database.  The difference between a default database and other databases is the default
database   doesn't   have   a   name.     Notice   the   highlighted   line   calling   the   method
addDataBase().  The first parameter is a string containing the driver name.  The second
parameter is a name you give this database object.  Any other module in your program
can use any database object you add to the global database object.  In affect it is a list of
databases your program has access to and is stored globally.   You cannot remove a
database from this list as long as there is still an object referencing it.  Oddly enough,
the reference count isn't reduced when the db object goes out of scope and is garbage
collected.  I assume they will fix this bug eventually.  For now, you need to remove that
reference by re­assigning the object to the default database.
If you fail to remove named database objects, or fail to remove all references to
them,   you   will   receive   warning   messages   in   the   default   output   window   when   your
application   closes.     Many   developers   simply   ignore   these   messages   and   set   there
applications up to be launched from screen icons rather than run inside of a terminal
window.  If there is no default output device (like a terminal window) you simply don't
see these messages.
Notice   how   I   had   to   launch   a   login   dialog   as   the   initial   screen/form   for   this
application.  When we get to the chapter covering this application you will see that the
login dialog  had to launch the actual main  screen/form  once it completed  the login
process.  This isn't the pinnacle of OOP benefits.

Chapter 2 – Cautionary Information

31

Why did I have to launch the login dialog as the initial form?  Application design.
In order to have combo boxes populated from various tables in your database, you have
to actually have a connection to the database and those tables.   In order to get that
connection, you have to ensure you have a username and password.  You cannot assume
the database will allow free access to anyone who wants it.  In fact, the current wrapper
provided by Qt doesn't allow you to connect without a username and password, even
when PostgreSQL allows this as we have seen.  Now my login dialog is tightly coupled
with the application.
If you choose to not have any combo boxes or database populated pick lists on your
main form, you can write a generic login dialog which can be popped up after your
main form has been created and displayed.  This generic dialog will be loosely coupled
with your application and infinitely re­usable.   The problem is that a developer rarely
gets to make the choices about what is and isn't on a form.  Users want it all and they
don't care how you have to warp the architecture to produce it.
2.5 Garbage Collection Restrictions
Java rots your brain.  I really admire developers who can easily slide between Java
in the morning and C++ in the afternoon without ever creating a memory leak on any
system and without using tools to grind their application checking for memory leaks.
My personal guess is that there are about five such people in the software development
universe.  I have no idea who they are, but I firmly believe there cannot be more than
five of them.  I especially doubt that number is increasing.  
When you are programming in Java, you have to allocate everything except the
scalar  types  with  new.    The  JVM  keeps  track  of  your  references  and  does  garbage
collection   whenever   it   deems   garbage   collection   is   appropriate.     C++   automatically
cleans up stack allocated variables when they go out of scope, but variables allocated
via new must be physically killed off by a call to delete.

32

Chapter 2 – Cautionary Information

Qt tries to aid in this by telling you it deletes all objects which are derived from
QObject.   I have seen this statement in a lot of documentation, and I'm  not exactly
buying it.  Actually, it is mostly true, but telling people this is causing more problems
than it is solving.  The main problem occurs with QSqlDatabase.  You have to clean up
the references yourself.  Earlier I showed you some code where I had to re­assign our
pointer to the default instance in order to free the reference, then I was able to remove
the database from the list of databases.
Why do we find ourselves in this bind?  Location, location, location.  QSqlDatabase
is global.   The instances you declare of it tend to be on the stack rather than on the
dynamic heap.
QSqlDatabase db = QSqlDatabase::addDatabase(driverName, qtDbName);

Only dynamically allocated objects can be removed by the delete operator in C++.
Objects allocated on the stack are supposed to be cleaned up with the stack clean up
prior to return, but you cannot remove them.   Because you cannot physically delete
stack allocated objects yourself, you cannot get rid of the references to global objects
cleanly.
But when the object went out of scope it should have been garbage collected, right?
No.  It was made available to garbage collection, but each platform implements garbage
collection at a time and place of its own choosing.  The only way  to clear the reference
was to re­assign my stack object to the default database connection prior to exiting the
enclosing block.
db = QSqlDatabase::database();

// clear connection to avoid error

Chapter 2 – Cautionary Information

33

2.6 More Database Issues
Almost all of the examples I find floating around the Web show how to use the
default database connection, not a named connection.  Why should you avoid using the
default database connection?  Come on, think about it, you know the answer.  Module
re­usability.  If you always pass in a string with the name of the database as Qt has it
stored, you can call your modules/classes from any application you develop.  It doesn't
matter if that connection is the first or the 50th connection.  
You   will   find   the   xpnsqt   application   is   coded   quite   differently   from   the
mega_zillionare application used in other books in this series.  The main.cpp for xpnsqt
appears earlier in this chapter.   It is the one we have been discussing with respect to
database issues.  I didn't notice it when working on Ubuntu 8.10, but when working on
SuSE 11.x I was seeing error messages like the following:
roland@roland-desktop:~/megaqt$ ./megaqt
QSqlDatabasePrivate::database: unable to open database: Access denied for user
'roland'@'localhost' (using password: NO) QMYSQL: Unable to connect
Successfully connected to database

The instruction which tossed this error wasn't the open statement.  It was the call to
make a copy of the database instance.
QSqlDatabase db = QSqlDatabase::database( m_qtDbName);

I must say I was really taken aback by this.  All of the information you could find
on­line said you needed the main.cpp file to declare your first instance of QSqlDatabase
so it would be owned by the last module to complete execution.  Most examples I could
find did it pretty much the way I was doing.  It appears that when you attempt to get a
copy or instance of an existing database connection, the method returning that instance
automatically tries to open it for you.  Quite the little helper isn't it.   “The road to Hell
is paved with good intentions.”  A lot of truth in that statement.
There was a slightly larger shock waiting for me when I ran the xpxnqt application
and saw the following in my terminal window:

34

Chapter 2 – Cautionary Information

roland@lgkl-destop:~/xpnsqt2$ ./xpnsqt2
QInotifyFileSystemWatcherEngine::addPaths: inotify_add_watch failed: No such file
or directory
QFileSystemWatcher: failed to add paths: /home/roland/.config/ibus/bus
Bus::open: Can not get ibus-daemon's address.
IBusInputContext::createInputContext: no connection to ibus-daemon
QSqlDatabasePrivate::database: unable to open database: "FATAL: database
"roland" does not exist
QPSQL: Unable to connect"
About to delete dialog
Dialog deleted, now clearing database

When you look through the various support forums and email lists on the subject of
Qt   programming,   you   will   find   quite   a   few   hacks,   suggestions,   and   work   arounds.
Everybody seems to be happy simply getting one to three lines of code which makes the
error go away.  They don't seem to be interested in actually fixing the problem.  In this
case,   the   problem   was   caused   by   someone   trying   to   be   helpful.     It   only   became   a
problem because a lot of other people tried to be helpful telling people they needed to
get an instance of the database object in their main.cpp file to keep it from going out of
scope during the life of their program.
What we really need to make things work cleanly is our main.cpp to declare a driver
for the default database connection and get a copy of the instance.   We need a driver
which will not throw an error trying to connect when a method tries to get a copy of a
partially configured entry.  
I guess it shouldn't be any surprise that Qt comes with its own version of SQLite on
most platforms.   I could not find an example of this anywhere I searched, but this is
basically what you need to do.  We will see this done in the megaqt (mega_zillionare)
example, not the xpnsqt example.
If you make a typo in your driver name, and you happen to have launched your
application from a terminal window, you will see a helpful error message along the lines
of the following:
roland@roland-desktop:~/megaqt$ ./megaqt
QSqlDatabase: QMYSQL driver not loaded
QSqlDatabase: available drivers: QSQLITE QMYSQL3 QMYSQL QPSQL7 QPSQL
roland@roland-desktop:~/megaqt$

Chapter 2 – Cautionary Information

35

Of course you might have the driver typed correctly and even see the name of it in
the list of available drivers.  In that case, you are using a static Qt library.  In the source
file which is actually making reference to the driver you need to type the following
macro:
Q_IMPORT_plugin(qsqlmysql)

and in the .pro file you need to add:
QTPLUGIN +=qmysql

Here   is   another   beautiful   error   message   which   will   have   your   head   slamming
against the keyboard:
QSqlDatabasePrivate::removeDatabase: connection 'blah' is still in use, all
queries will cease to work.

I loved seeing this message.  It took a long time to figure it out.  This is the message
you get when you forgot to remove your last reference to a database before calling
removeDatabase().  I've already shown you the fix for it.  Simply assign your database
variable to the default database before calling remove.  That will clear the reference in
most cases.   You get this error even if the database is closed because the reference
counter is greater than zero.  
2.7 Pitfalls of Mandatory Passwords
You have already seen a few examples from the world of PostgreSQL where it will
let a properly configured user connect to a database without forcing a password prompt.
The database itself has to be told to trust local system security before such things are
allowed.  
roland@lgkl-destop:~$ psql -d postgres
psql (8.4.4)
Type "help" for help.
postgres=#

36

Chapter 2 – Cautionary Information

Most of your security type geeks make it a point to turn this feature off on any
newly created system.  The last thing they want is someone with access to a sensitive
database (like one full of credit card info) walking away from their terminal without
locking it.  Sometimes the user community wins and sometimes it doesn't.
I'm   pointing  this   out   in   the   cautionary   section   because  it  can  really  screw  your
design.   Actually, it can make entire applications impossible to develop.   In the next
chapter   you   will   encounter   our   XPNSQT   application.     While   it   does   not   try   to
download, install, and configure PostgreSQL automatically for the user, it does try to
create a missing database.  
You should not be surprised to learn that creating a year specific expense database
will require user input.   It should surprise you even less to learn that the application
builds a SHELL command on the fly using the tax year and other information to create
the database.  
cmd = "createdb " + db.databaseName() + " 'Expense Information';";
int x = system( cmd.toAscii());

The system() command in C/C++ does not create a shiny new terminal window
where a user could view and respond to prompts that might be encountered when the
command runs.  If someone needs or wants that capability, they will have to modify the
application to use QProcess provided by Qt.
I   need   to   point   out   that   “createdb”   is   a   helper   program   provided   with   the
PostgreSQL   database   package.     It   is   expected   to   reside   in   a   directory   which   is   in
everyone's path.  There are actually quite a few of these helper programs.  Where they
get installed depends upon your platform and database version.
roland@lgkl-destop:/$ dir
clusterdb
createlang
pg_dump
pg_resetxlog
createdb
createuser
pg_dumpall pg_restore
roland@lgkl-destop:/$

/usr/lib/postgresql/8.4/bin
dropdb
dropuser
oid2name pg_controldata
pg_standby postmaster reindexdb vacuumlo
droplang
initdb
pgbench
pg_ctl
postgres
psql
vacuumdb

Chapter 2 – Cautionary Information

37

2.8 Database Frailty
If   you   work   in   IT   long   enough,   you   will   find   out   there   are   reasons   for   most
everything.   Many times you will find that none of those reasons were good, but a
course of action was chosen anyway.  This is especially true of database products.
On the OpenVMS platform, we have a wonderful database called RDB.   It was
originally developed by DEC (Digital Equipment Corporation) and is now owned by
Oracle.    No,  it  isn't  the  Oracle  database  you  now  see  running  on  useless  Windows
boxes,   I'm   talking   about   a   good   database.     RDB   is   completely   integrated   with   the
operating system.  It uses the ACLs (Access Control Lists) and rights identifiers from
the same UAF (User Authorization File) as the operating system.   In short, it doesn't
have   to   provide   some   hokey   roll­your­own   user   administration   and   rights   identifier
system like almost every other database on the face of the planet.
OpenVMS is the only operating system which truly clusters, many claim it, but only
OpenVMS  actually delivers it.   The OS  kernel understands the concept of a record
along with the concepts of ACLs, rights identifiers, logicals, and user privileges.  This
enables the kernel to support and utilize a lock manager which has complete recovery
built into the system boot process.  This enables the cluster to have a distributed lock
manager that works in unison with every lock manager on every node in the cluster.
The   lock   managers   provide   the   foundation   for   the   distributed   transaction   manager
which allows a transaction to span multiple databases, indexed files, journaled flat files,
and message queues with full rollback/commit capabilities.  It may not be sexy, but it is
data Nirvana.
RDB allows you some choices with database creation.  You can create a single file
database, or you can spread your database across multiple drives and directories.  Single
file databases aren't speed demons, but they are pretty cool.  You can lose the system
disk which had RDB running, create a shiny new system disk with RDB on it, boot, and
tell RDB to open your database.  All of the information needed is stored in the single
file database and its directory.  You have complete recovery.  It's a bit trickier with the
multi­file­disk version.

38

Chapter 2 – Cautionary Information

I'm bringing this up to you now to let you know that none of the databases we will
be covering have that capability.  Most PC users think about the cheapness or ease of
use when choosing a database, not about what happens when things go bad.  I guess that
is kind of understandable since a lot of those people are using a computer with a single
hard drive they rarely back up and never take the time to create a full image backup.
When the spindle spits a platter onto the floor they are well and truly pooched.
Professionals, on the other hand, have made a living designing systems on midrange
and mainframe computers.  We've had to build in fault tolerance to levels which would
make the average PC user faint if they tried to wrap their heads around it.
I'm  on my soapbox now so that you will understand just how shaky things are.
Every database we will be covering has the exact same flaw:  
If   you   lose   the   disk   containing   the   database   engine   directory   and   have   to
reinstall on a new drive, all of your data is toast.  It doesn't matter how many
drives you spread the data across or how religiously you backed it up with
some third party tool.
The flaw is caused by the database engine keeping all of the schema, user, access,
space,   and   proprietary   information   in   the   directory   with   the   engine,   or   some
subdirectory thereof.  When you lose that information, you lose touch with the data, no
matter where it is stored.  MySQL, as well as most of the others, tries to hide this fact
from users by making the default location for database creation the same directory tree
as the database engine which puts it on the same spindle as the operating system.  This
way you lose it all together and don't realize the flaw.  Of course, creating a production
database on the operating system disk drive is a systems management no­no of biblical
proportions.
I found this out about PostgreSQL the hard way.
No binary backup made with any backup tool is of any use if it cannot restore your
database engine directory to exactly what it needs to be so database information isn't

Chapter 2 – Cautionary Information

39

lost.  The “backup method” used by all of these databases is for you to write a script (or
use a provided utility) which dumps the data into a text only CSV (Comma Separated
Value) file.  Once you recreate your database from the script files (you did use a script
instead of just keying the definitions in at the interactive prompt didn't you?) the CSV
files are to be imported into their corresponding tables.
If you aren't an IT person by trade, that pitfall probably doesn't seem so bad.  I am
an IT person by trade.   The first two versions of my expense tracking software used
standalone indexed files which I kept in different directories for different years on a
separate disk drive.  I also backed that drive up religiously.  I could easily recover from
any situation prior to moving to an Open Source relational database.  Now, in order to
be able to recover, I have to quintuple my storage requirements.  Once all of the data is
entered  and  verified,  I   must  export  each  table  to  a CSV  and  backup  that  expanded
version along with the scripts to create and restore the CSV.
What I'm showing you will be good enough for your own personal development.  It
may even be good enough for a small company as long as you are religious about CSV
export and backup.  Some companies have been burned pretty bad by this frailty.  I have
seen some companies map the system boot disk (which contains the database engine and
proprietary information) to a RAID 6 volume on their SAN so they could be protected
from two spindles burning out at the same time.
Only you can decide what your data is worth.  Don't make that decision after you've
developed the application.
It's difficult for a regular PC user or even the average Open Source developer to
grasp just how critical this issue is in a production environment.   If your database is
currently approaching 1TB in size and is filled with binary data (mostly numbers, not
much text) you will need 5TB of contiguous free disk space to create your CSV file.
Right now the biggest SATA drive you can buy for your PC is 2TB so unless you link
three of them together with a RAID controller, you cannot backup.

40

Chapter 2 – Cautionary Information

2.9 Main.cpp for What?
One of the larger issues I have with the “accepted” method of Qt development and
its “one directory tree” philosophy is the concept that every application should have a
main.cpp file.  I find this in all of the books I look at and most of the on­line examples.
It appears to be the will of the Qt programming community.
Let me be the first to tell you, this is a disaster waiting to happen!
Yes, I really wanted one sentence all by itself like that.  You need to pay attention to
this issue.   If every project has to have a main.cpp and they are all custom for that
project, you have a ticking time bomb on your hands.  Let me tell you a story.
Back in the days of my yoot, I worked at a DEC VAR (Value Added Reseller.)
Besides   selling   DEC   equipment,   OpenVMS,   and   its   layered   products,   we   sold   a
customized ERP system.   It was like many of the ERP systems of its day.   All of the
order entry modules were named OEnnna so the main order entry source file would be
something like OE710 and the supporting source files would be named either OE710A,
OE710B, OE710C or OE711, OE712, OE713, depending upon what they where and
how   the   developer   split   things.     (There   were   rules,   but   they   aren't   relevant   to   this
discussion.)
We had no source code control system.   Each customer would have a temporary
directory tree set up for them by the System Analyst assigned to the project.  We would
all take source from that tree and work on it in our own little development accounts.
When we had completed our coding and testing the Systems Analyst would be given
information on where to pull the source from our account and what files to pull.  If it
passed testing, they put the new source into the client source tree.
If business was going good, we never had enough disk space to go around.  Once a
client had been installed and a few days of “shake out” time had passed, their tree
including   source,  data,  etc.   was  backed  up   to   a  removable  platter   and/or   tape,   then
deleted from the system.  Many times there were races between a tape restore process
and   getting   the   developers   to   delete   enough   items   for   the   restore   to   complete
successfully.  Some of our clients actually purchased enough disk space that we could
store a copy of the source files which had been modified for them out on their systems

Chapter 2 – Cautionary Information

41

as well.  A token few even dropped the $1200 it cost for that 300 baud modem so we
could dial in to support their systems.
So now, scattered across three disk drives and literally thousands of subdirectories,
were various copies of every source file in the system.  You can guess what happened
when a new programmer started.  They would be given a list of custom changes to one
module and would invariably pluck that module from a directory tree other than the one
the System Analyst (SA) had created.  Since they had no idea as to what changes had
already been made for that client, they had no idea that some things were missing from
this   version.     The   SA   would   find   that   out   the   hard   way   when   they   got   around   to
integration testing.
Oh, there was one other thing which would happen with new people.  They wouldn't
create a different subdirectory for each project they were working on and leave it until
the client had been removed from the system.  Given all of our time was billable, we
didn't just get to sit around waiting for bug reports to come back from the SA.   We
handed off our stuff and got a new assignment at that time.  If you had just gotten done
modifying IN110 for client A, the next SA may give you the exact same module to
modify for Client B since you were already familiar with it.   Half way through your
modifications the first SA would come back with bugs they needed fixed right away due
to an installation date coming up.  You guessed it.  They would pull that module into
their working directory and walk on everything they had done for Client B without
knowing it.
I'm pointing this out because it is a massive pet peeve of mine.   It is physically
impossible to say enough bad and degrading things about code management systems
which allow directories to be created inside of them or which enforce some kind of
directory structure on a project.   These are not code management tools, they are code
disasters in the making.  Naturally CVS and the other tools which support this happen to
be the free stuff used by many, if not all, Open Source projects.  These are bad bad bad
bad bad bad things.  

42

Chapter 2 – Cautionary Information

A quality code management package will allow a source file name to exist  once
within   a   code   library.     If   you   want   to   fork   off   development,   you   have   to   create   a
completely different code library which is optically isolated from the first code library.
A developer (or build procedure) can pull a specific generation of any element at any
time without having to know what directory the thing was squirreled away in.   When
you   issue   a   command   like   “SHOW   HISTORY   OE710.BAS”   you   get   the   complete
history for the element and each generation is either a linear or flat progression.  (Linear
=   put   back   with   changes   from   prior   version,   Flat   =   put   back   without   any   changes,
sometimes programmer error, other times result of migration from Development to Test
to Production to Support.)
For a better explanation on how a quality code management system works read,
“The Minimum You Need to Know to Be an OpenVMS Application Developer” ISBN­
13 978­0­9770866­0­3.  In particular you want to focus on the chapter covering CMS.
Readers looking  for  general information on  code management  systems can  start
here:  http://en.wikipedia.org/wiki/Revision_control though the author(s) don't appear to
understand the problems of allowing branches and forks  within  the same repository.
What they do talk quite a bit about is how CVS can, in many cases, merge the code
from one fork/branch with another.  That's a scary thing Maynard.
2.10 Transaction Integrity
This topic is so important that I broke it out into its own section.  While the SQL
interface provided by Qt can do a great many things, one thing it is not designed to do is
provide transaction integrity.  The database engine, or the driver providing access to the
database, has been made completely responsible for transaction integrity.  This means
you are personally responsible.
Far   too   many   developers   expect   any   SQL   interface   to   provide   them   complete
transaction integrity.  I have seen many a catastrophe caused by stupid developers who
break the cardinal rule of database application development.
Keep your transactions short.

Chapter 2 – Cautionary Information

43

That's it.  That's the one rule you have to remember and it is the one rule most of
you ignore.  I've even been guilty of it.  Actually I've had business units at client sites
force   upon   me   application   design   rules   which   meant   I   either   created   a   massive
transaction or I wrote an awful lot of recovery code which may or may not work in the
event of a system or hardware failure.
Please consider the applications being presented in this book.  While they “could”
be multi­user, they are really designed to be standalone.  (If two different users with the
XPNSQT application try to create a new tax year database at the exact same instant, one
of them is going to have a less than happy experience with the application.)
When we design standalone applications, we seldom worry about multi­user issues
or the size of our transactions.  One client site used to have a rule which was enforced in
code reviews that no database write transaction could contain more than 300 records
before a commit had to occur.  While hardware improved, they kept this rule in place
and currently have applications in production which still adhere to this rule.   While it
might sound stupid today, that rule existed for two reasons:
1. Database lock timeouts
2. Snapshot file size
If you have 400 different users all attempting to do some bulk insert of 20­300
records on the same table at the same time, lock timeout can be an issue.  It certainly
was an issue back in the early 1990s when disk access was comparatively slow so each
of those users need one to three seconds of lock on the same table.  You don't have to be
a math major to figure out that at two seconds each:  300 * 2 = 600 seconds /60 = 10
minutes.  Basically every user past the 2 minute mark was going to go into a rollback
state due to time out which, at the time, was even less efficient than a commit.
Today we have similar issues with the freely available databases on our PCs.  While
these issues aren't multi­user per se, they amount to the same thing, especially if your
application is being accessed via a Web site with each connection having its own thread.
Imagine how things would fail at eBay with 100,000+ bidders all trying to update the
bid history table simultaneously if they each needed a one second lock on the entire

44

Chapter 2 – Cautionary Information

table?  They don't have to be bidding on the same item, just bidding on AN item to force
the need for an entry.

Have you ever been a Project Manager?  

Have you ever been a Business Analyst?  

Have   you   ever   read   SDLC   (Systems   Development   Life   Cycle)
documentation for a shiny new project which involves a database?  

Have you ever sat in a meeting with the IT team and the MBAs where they
were arguing about what new things needed to be purchased to make this
project work?

What is the one thing which gets questioned on every project?
Oh come on.  We have all sat in college database classes and been told the reason
relational   databases   can   provide   a   rollback   capability   is   because   all   of   the   pending
changes are kept off in a snapshot file or area until the COMMIT occurs.  We have all
sat there at our terminal and typed something like:
DELETE * FROM PERSONNEL;
xxxx rows deleted
ROLLBACK;
SELECT * FROM PERSONNEL;

And simply been amazed to see all of the data on screen.   Then we repeated the
same exercise with a COMMIT instead of a ROLLBACK and saw zero rows make it to
the report at the end.  No matter what we did, that data was gone for good and had to be
reloaded from the source file.  Some of the older database systems would even let us do
the SELECT after the DELETE without either a COMMIT or ROLLBACK so we could
see the impact of the DELETE prior to deciding whether to COMMIT or ROLLBACK.
I really feel sorry for DBAs when we are sitting in those meetings.  It doesn't matter
how many times I point this database example out, or how many times they write the
formula from the database vendor on the board, MBAs simply can't understand why we
need   to  spend  so  much  money  on   disk   space  that   will  never  be   allocated  to  actual
database storage.

Chapter 2 – Cautionary Information

45

Perhaps it is time to re­hash another lesson here since many of you will be PC users
and have no idea what disk storage for real computers costs.   Yes, you can find 1TB
SATA hard drives for under $100 through many major retailers these days.  The price
seems to drop on them every couple of months.   These drives, however, don't really
work for real computers.  Real computer systems obtain much of their storage from a
SAN (Storage Area Network) device.  This device may be co­located in the computer
room, or somewhere else in the country.  
Many of the 1TB SAN units require a forklift to be moved and their own 200AMP
service to operate.   These are high availability devices.   Every drive, except the hot­
swap in cabinet spares, stays spinning while the unit has power for as long as it has
power.  When the unit senses a failure, it can recreate the failing/failed drive on one of
the internal spares while the operator replaces the failing/failed drive with a new one off
the shelf.  When the unit senses a “quiet” time it will recreate the original drive in its
original place returning the in cabinet spare to the spare pool.  (Okay, some require a
system manager to issue a few commands, others will only recreate in place, but some
are this way too.  Let's not chase a red herring and lose sight of the lesson.)
The SAN allows the systems managers to configure any number of spindles as a
logical disk drive available to one or more computer systems.   Those spindles can be
configured as raw storage or as various RAID levels (which is what allows the hot swap
without data loss.)  Many of the most robust SAN systems used only SCSI disk drives
because they were built far tougher than their IDE counterparts.  It was not unusual to
see a $300+ price difference between SCSI and IDE for the same size drives from the
same manufacturer.  Later, some sleazy drive manufacturers tried simply putting their
SCSI logic cards on top of their IDE manufactured drives as a way of increasing profits.
They were quickly weeded out of the marketplace when replacement drives from them
started lasting days instead of years inside of the SAN cabinet.
You   see,   the   IDE   drive   (which   is   now   morphed   into   SATA   and   PATA   drive
interfaces over the same platter set) achieves its five year MTB by spending much of its
life   powered   off.     Of   course,   marketing   has   been   able   to   play   this   up   as   “Green”
technology  and  many  have   even   gotten  Energy   Star   ratings.     Once  again,  spending

46

Chapter 2 – Cautionary Information

much of your life powered off makes this possible.
Life in the SAN is different.  The SAN must provide high availability.  The reason
SANs were invented was to provide high availability and make disk management easier.
Just how many users do you think will sit around waiting to place a bid if they have to
wait 30 seconds for one of the spindles the database is spread across to spin up and for
the database to verify its own structural integrity?
Some vendors are now trying to blend high availability with cheap technology in
newer SAN devices. This requires two or more sets of standby racks since each standby
needs to match the device type it will dynamically replace.  
Other vendors are simply relying on cheap individual spindle prices and massive
replication.  While the implementations vary, most simply require one to six additional
cold mirror spindles for every hot spindle.  From the system manager perspective they
simply assigned a primary 1TB spindle and a mirror spindle, but internally the SAN
allocated twelve additional spindles to cold mirror those.   The software in the SAN
attempts to regulate the amount of hours each spindle has to be hot.  When it gets close
to time it spins up one of the cold mirrors and begins the update process directing most
new traffic to the new spindle.   Once the update is complete, the original hot spindle
shuts down and cools while awaiting its next active time.  Eventually someone will get
this technology to work really well, but I've been hearing mixed things about it for a
while now.  
One of the big drawbacks with SAN in general is the bandwidth required to flash
copy 1TB between hot and cold spindles.   By the time that issue gets resolved 2TB
drives will probably cost around $50 and the problems will start all over again.  A major
reason a lot of SAN technology stuck with 36GB SCSI drives was the fact they could
copy that much in just a few seconds and do all of the work on the SCSI controller
without involving the SAN CPU.  Part of the “high availability” requirement means that
a database request won't time out while you are in the middle of a hot swap.  
How many of you have actually sat through a full format of your 1TB SATA drive?
Not one of those “quick formats” which just writes out the file allocation table and
updates the MBR, but one which actually writes a pattern to each drive sector?   You
aren't   even   doing   IO   at   that   point   for   most   of   these   new   drives.     The   drive   has   a

Chapter 2 – Cautionary Information

47

command which tells it to do that and it still seems to take forever.  Imagine just how
widespread SAN technology would be if that was how long it took to “hot swap” a
spindle?
Enter our project DBA.  He or she has to sit in the project meeting and say that if
you plan to have 2TB of data in your database, or one of the tables could have in excess
of half a billion records, that they need 1TB of snapshot space to ensure all users access.
They have to sell that to an MBA with a half a million dollar price tag for the SAN plus
the cost of getting yet another 200AMP service installed in the computer room and the
additional air conditioning capacity.  In some cases it means having to put the SAN in a
different data center or having to build an additional data center because you are already
drawing the maximum amount of power your municipality will allow an office business
to draw.
Laugh all you want at not being able to get the electricity to run the device.  I have
seen that happen more than once.   One client built an office building in a shiny new
office park where the buildings were limited to 1000 AMPS each.  It didn't sound bad
until   upper   management   started   putting   more   people   in   the   building   than   originally
planned.  Before everybody got moved in, the data center didn't have enough power to
run   the   single   SAN   it   was   supposed   to   run.     Adding   insult   to   injury,   the   Business
Recovery Plan on file stated that the data center in the new office building would run
the company in the event they lost the primary data center … and I never saw it get
updated.
Many people erroneously believe that it is the responsibility of the DBA to ensure
integrity   in   the   database.     Nothing   could   be   further   from   the   truth.     It   is   the
responsibility   of   the   DBA   to   ensure   all   of   the   constraints   are   in   place   to   ensure
referential integrity exists within the database, but it is the application developer and
Business Analyst's responsibility to ensure that referential and domain integrity matches
the business requirements.  It is the responsibility of the DBA group to put in place a
backup procedure which ensures recoverable archives of the database get created, but it
is the responsibility of the system managers to ensure those procedures get executed and
to coordinate the handling of backup media.   It is the responsibility of the Business
Analyst to ensure the backup and recovery process occur within an outage window the

48

Chapter 2 – Cautionary Information

business unit is willing to live with and to obtain the funding necessary to get backup
and recovery to occur within the outage window the business is willing to live with.
Lastly,   it   is   the   responsibility   of   the   application   developer   to   ensure   their   software
provides transactional integrity.
If you, the application developer, are not a partner and friend to the DBA on your
project, you are going to have a miserable project experience.  If you start a transaction
at the same time you initially connect to the database, but don't actually have data or
complete the transaction until a user provides some response, you are going to be called
on the carpet when your program has resources locked for hours.  If you try to select
every row in the database for update without first obtaining a count to see if that is
reasonable, you are going to have a very bad day.
Perhaps the biggest problem you will ever encounter in your career is the different
definitions “transaction” has throughout any given business.  

To the DBA, a transaction is a write or delete and commit to a single table.
You might get them to agree to multiple tables within a single database, but not
something spanning multiple databases or data sources.  

Your business people view an entire business process as a single transaction.  If
you are working in a wholesale business supplying retail/dealer locations, the
business is going to consider a stock order coming in from the dealer all the
way through the order acknowledgment with in­stock and back order indicators
along with pricing going back to the dealer as a single business transaction.
This   “transaction”   not   only   encompasses   checking   the   inventory   at   all
warehouses, but also checking available dealer credit and available shipping
methods.   It shouldn't take a rocket scientist to figure out that much of this
information will be provided by either different databases or interfaces provided
by completely different systems.  

Many portions of IT will refer to the business transaction as a multi­segmented
transaction.  That definition is important, because once you define the segments
you can bust up the overall transaction into restartable units of work.  Each unit
of work will be a transaction a DBA can like but your logical transaction will
require   the   successful   commit   of   many   physical   transactions   before   it   can

Chapter 2 – Cautionary Information

49

commit or be considered successful.
If you are lucky enough to be working on OpenVMS, it has a distributed transaction
manager (DECdtm) which allows you to commit and rollback transactions spanning
multiple  data  sources  without  having  nasty  database  locking  issues.    When  you  are
working   on   lesser   platforms,   you   have   to   provide   your   own   recovery   logic   for
segmented transactions.   What you cannot do is keep a different transaction open and
pending in every database you are using until you know you are completely done.
Many developers are absolute geniuses when it comes to coding in C/C++, Boost,
STL, or a host of other tools and languages.   Many of them have only coded Open
Source or standalone applications on a PC and while they may be coding savants, they
still get fired when they try to work for big companies using real computers.   The
reason they are canned is that they don't understand transactional integrity.  
2.11 SQL != SQL
I've said this before and I really catch a lot of grief for it, but as a professional
developer you have to believe it.  
There is no SQL standard.
Yes, I know the entire ANSI membership began hunting me with pitchforks and
torches the instance I typed that line, but it's really the truth.   Yes, there were some
standards published and yes, every SQL engine for every database will claim to support
ANSI standard SQL, but less than half of the commands you type will work on more
than one database product, even if the database tables are declared exactly the same.
Every   database   you   encounter   supporting   some   flavor   of   SQL   will   exploit
“implementation   defined”   holes   in   the   “standard”.     They   will   also   “enhance”   the
standard at every opportunity.

You have been reading an excerpt.
Please visit http://www.theminimumyouneedtoknow.com to learn more about this
book series. You can also find out how to purchase works by this author.