Monday, January 29, 2018

A Couple of SQL Relay on Ubuntu How-To's

A couple of people have recently asked for some step-by-step tutorials detailing SQL Relay installation and configuration on various platforms. So, there's a new Gadget on the right hand side of this blog called SQL Relay How-To's that will contain these tutorials.

I just added 2 for Ubuntu 16.04.

Check them out!

Friday, December 8, 2017

Firstworks GIT Migration

I'm fairly well known, among friends at least, for liking to get every last mile out of vehicles, equipment, gear, and just about everything else. Every last mile. The night before last, I discovered that I had gotten every last mile out of Sourceforge's CVS service.

I'd made a couple of changes, run a commit, and bam!


CVS commits are NOW DISABLED! This was first announced on October 5th, 2017:

This project's data may be converted over to a new SCM. Use the project's
menu to see where the current code is kept:

To access the CVS data, either use a pserver checkout or an rsync backup.
In the following commands, replace PROJ with the project name and MOD with
the module name:

  cvs -z3 co -P MOD

  rsync -aiv /dest/dir/

Conversion instructions for svn and git are available here:



Well, I wasn't too upset. It's not like I didn't see it coming. A few years back I tried to get git working on all the old platforms in the compile farm. That ultimately failed, but I worked out a better solution last month and I've been trying, off and on to get my CVS repos converted to GIT ever since.

Good thing! I needed the experience of all of the failed attempts, and some advice from a buddy of mine to finally get it working today.

So, as of today, all Firstworks projects have been migrated from Sourceforge-hosted CVS to Sourceforge-hosted GIT.

Rudiments is available via:

git clone git://

SQL Relay is available via:

git clone git://

RIP CVS. Thanks for the memories!

Tuesday, November 7, 2017

SQL Relay 1.2.0 Release Announcement

Version 1.1.0 of SQL Relay, the powerful connection pool, load balancer, query router, and database proxy, is now available.

ODBC Improvements

The main focus of this release is ODBC improvements.

ODBC is unimaginably complex. To illustrate this point, the ODBC Driver for SQL Relay consists of 11223 lines of code, while the SQL Relay Client Library that it wraps only consists of 8748 lines. The API also provides several different ways do to do the various things, and different apps use different ways. It's a daunting task to implement even the majority of commonly used features, and then there's always that one app that uses some particular feature. As such, the ODBC driver hasn't gotten the attention that it deserves.

This release brings many, many major and minor improvements to the ODBC Driver for SQL Relay. It is especially improved when used with an ODBC backend, and even more so when using ODBC on the backend to access MS SQL Server, a very common use case.

The improvements are far too numerous (and in most cases, subtle) to describe here. If you had an ODBC app that was having trouble with SQL Relay, try it again.

Windows Improvements

There were basically build problems with older versions of SQL Relay that prevented it from running on some systems, and prevented it from running correctly on others.

The vast majority of these problems have been vetted and solved.

As with ODBC, if you had a platform that had trouble running SQL Relay, try it again.

32-bit Output Bind Length

This release also remedies a significant oversight. On the client-side, and in the protocol, input and output bind variables have always had a 32-bit length. Until this release, though, due to an oversight, in the server API, output bind variables had 16-bit lengths. This basically made it impossible to fetch a string longer than 32678 bytes from the database. Some databases limit varchar fields to this length, so it's not a problem with those databases, but it created significant problems in some distinct cases.

This oversight has been remedied. In fact, this is the tiny, but significant, ABI-breaking change that caused the bump to 1.2.0 from 1.1.0.

Bug Fixes and Improvements

This release also includes the standard array of random bug fixes and minor improvements. Full Changelog follows.

      fixed subtle error in sqlr-import that could cause it to skip empty/NULL fields
      implemented getCurrentDatabase for odbc connections
      implemented selectDatabaseQuery for odbc connections
      added NCHAR, NVARCHAR, NTEXT, XML, and DATETIMEOFFSET types, updated odbc connection module to recognize them
      added --with-windows-version to configure.vbs
      enabled "liveconnection" test for "Lost connection to MySQL server during query" error
      made server-side string outputBind() method's valuesize 32-bits
      added missing mapColumn() call to sqlrservercontroller::getField()
      fixed var directories in Windows deployment projects
      added run-as-Admin requirement to Windows installer
      implemented ODBC SQLProcedures, SQLProcedureColumns, SQLGetTypeInfo, SQLPrimaryKeys, and SQLStatistics, though currently they only work when using the odbc connection module
      implemented ODBC SQLTables to get schema and table type lists, though currently only works when using the odbc connection module
      ODBC SQLProcedures, SQLProcedureColumns, SQLColumns, SQLTables, SQLGetTypeInfo, SQLPrimaryKeys, and SQLStatistics properly set the error now if there was one
      ODBC SQLError properly cycles through the error records now
      updated ODBC SQLGetInfo(SQL_DRIVER_ODBC_VER) to return a value corresponding to the value set by SQLSetAttrInfo(SQL_ATTR_ODBC_VERSION)
      fixed string outputBind() signature in odbc connection module
      fixed a couple of short -> int16_t/uint16_t errors in odbc and mysql connection modules
      ODBC SQLBindParameter(in/out) calls outputBind() now, to work with apps like Delphi which broadly use in/out for out parameters
      refactored odbc connection module's methods to get object lists to support dot-separated object identifiers
      various odbc driver improvements
      updated odbc driver to interpret SQL_C_(X)LONG types as (u)int32_t's rather than long's
      updated odbc connection module to use SQL_C_SBIGINT/SQL_BIGINT for integer binds, rather than SQL_C_LONG/SQL_INTEGER
      fixed uninitialized null/blob flags in sqlrclientprotocol::returnRow()
      various variables are now properly typed (SQLLEN vs. SQLINTEGER) in the odbc connection module
      added "divider on/off" command to sqlrsh
      fixed several cases where microseconds were represented by an int16_t made them all int32_t's
      parsing/generation of fractional seconds pays attention to length of value/format-string now
      fixed a bug that caused fractional seconds to be dropped sometimes
      odbc lazy-fetches now
      odbc driver fakes SQLBindParameter with data-at-exec by deferring the execute and buffering the data locally now
      bumped odbc MAX_COLUMN_COUNT to 384
      added a mars=yes/no flag to enable MS SQL Server MARS when using the odbc driver for MS SQL Server with the odbc connection module
      ODBC SQLGetInfo(SQL_USER_NAME) gets the schema from the backend when used with the odbc connection module now
      increased listen backlogs to 128 from 15/5
      normalize translation doesn't remove spaces around _'s any more
      implemented output bind null indicators properly for db2/informix
      odbc connection supports dynamic maxcolumncount/maxfieldlength now
      fixed but that caused the results of non-tree-based query translations to be concatenated
      updated odbc connection to fetch blob columns in chunks and not be bound by maxitembuffersize
      fixed a bug that could cause a buffer overrun when using maxitembuffersize with odbc, db2, and informix
      configure script finagles the multiarch dir for platforms where gcc -print-multiarch doesn't return anything, but the multiarch dir is necessary to find python3
      configure script can find php-7 on openbsd now
      node is used to run node-gyp.js now
      configure script looks for /etc/php7 now
      configure script looks for node-gyp under /usr/lib*/node_modules/nmp[6789] now
      php pdo api uses zend_long in place of ssize_t now
      fixed uninitialized ncols in mysql connection module

Rudiments 1.0.6 Release Announcement

Version 1.0.6 of Rudiments, the C++ class library for developing systems and applications, is now available.

This is mainly a bug-fix release, and most of the bugs were on older Windows systems.

ChangeLog follows:

  • fixed url user/password parsing
  • added setValues() methods to dictionary class
  • added --with-windows-version to configure.vbs
  • added definition for va_copy for older Windows
  • added some GSS/TLS ifdefs for older Windows
  • added HCRYPTPROV_OR_NCRYPT_KEY_HANDLE typedef for older Windows
  • added run-as-Admin requirement to Windows installer
  • implemented process::getEffectiveUser/GroupId to just return getUser/GroupId on Windows
  • SSIZE_MAX in the filedescriptor class is more accurate on Windows now
  • filedescriptor limits buffer sizes to SSIZE_MAX
  • fixed GNU strerror_r usage
  • worked around strerror_r bugs in older freebsd
  • fixed clobbering of errno in filedescriptor write/printf
  • prompt class assigns result of ftruncate for platforms where it's declared with attribute warn_unused_result

Friday, August 4, 2017

Visual Studio Missing "Open Project/Solution"


A very weird thing happened to me the other day...

I have a client that was having trouble running SQL Relay to run on Windows 7 x86. After getting a Windows 7 x86 VM working, I ran into some of the same problems.


Well, my x86 packages are built on Windows 8.1, with the correct switches for Windows 7 compatibility, but who knows, maybe I should just build it on Windows 7 to see if I get better results.

The Problem...

So, I installed Visual Studio 2013 Community, which is what I use on Windows 8.1, and got everything to compile and run. But, to build packages, I needed to use Visual Studio Pro 2010, because it actually supports building deployment packages, unlike the free versions.

No problem, I own a copy of that, so I installed it too.

Post-install, the UI looked weird and the File menu had an "Open File..." option but no Open Project/Solution, or New Project/Solution, or anything like it. Opening the deployment project with Open File just opened the file itself in a text editor.

What the heck?

The web suggested Tools -> Import and Export Settings... -> Reset All Settings.

This did nothing.

The Solution...

I ultimately discovered that installing VS 2013 first had caused the problem.

To uninstall 2013 completely, I used:

vs_community.exe /uninstall /force

...from the install DVD image.

To uninstall VS 2010 and start fresh, I used the "Uninstall a program" link in the Control Panel. I also removed the various things that I'd seen the VS 2010 installer install the first time, like Dotfuscator, Tools for Office Runtime, various SQL Server-related things, and Silverlight. Unfortunately I don't have an exact list of them now, and looking at it now, it's not clear what was installed by VS 2010 and what was installed alongside something else. It's also not clear how important removing them is, so it might not matter. I just did it to be thorough.

After that, I re-installed VS 2010 and the UI looked correct. Installing VS 2013 afterward didn't hose 2010 either.

All of this took hours and hours.


Why does it matter what order you install them in?

After much digging...

It appears that every time you install a new version of VS, it attempts to emulate your UI settings from any existing version. This works OK when upgrading from an older version of VS because it already existed prior to the invention of the newer version. If you already have a newer version installed though, the old version might get confused trying to make sense of its newfangled configuration. Apparently this happens when 2010 Pro tries to read the settings from 2013 Community.


Well, at least I'll know to avoid that in the future.

Sketchy Windows 7 x86 Activation


I bought a copy of Windows 7 Home Premium (32-bit) from a guy on eBay, and what I got in the mail was nothing like I'd hoped I'd get. I'd hoped for a new, in-the-box copy. Instead, I got a disc that said something like "Intended for distribution with a refurbished PC" on it, and an obviously peeled-off product key stuck to the back of the sleeve.


In hindsight, it was probably foolish to expect more for $27.99. Would it even work?

Well, kind-of. I was able to install it in VMware and the key worked at installation time, but when I tried to Activate Windows, it failed with an error saying that Microsoft had blocked that key!


So, maybe the guy bought a refurbished laptop which eventually died, and he resold the disc that came with it, along with the product key that he peeled off of the laptop???

Conceptually, that seems like the kind of thing that something one ought to be able to do. But, of course, logistically, if Windows 7 had already been activated on the laptop, then after it died, there's no good way for Microsoft to know that, or any process that I know of to deactivate a key, and it ends up being up to the new owner to sort it out.

Fortunately, I was able to do so, very easily.

MS has a new (well, new as of August 2017) online chat thing that you can use for customer support at I typed in my problem, it gave me a potential solution, which didn't work, and then asked me if it solved the problem. Clicking No gave me the option of chatting with a guy, and the guy was able to get everything going.

It did require a bit of legwork though. I had to take a photo of the product key and a screenshot of the eBay order and put them on the VM's desktop, basically as proof-of-purchase. Then, I had to go through some steps to let him take over the PC. He looked at the images, "convinced his supervisor" that I had legitimately purchased the product, generated a new key, activated Windows with that key, and left me a copy of the key on the desktop.


So, if you find yourself in a similar situation, you may not just be out $27.99. There is hope.

Windows 7 - Get Genuine!

I'm sure this has happened to someone else...

Years ago I bought a cheap laptop from WalMart, an Acer Aspire One 725 - 0802 to be exact, which came with Windows 7 Home Premium. Given how inexpensive it was, I expected to have to replace it a year later, but no, it just kept bumping along until the paint was worn off of almost every key. One day though, it just wouldn't turn on any more.

Between backups and the cloud I was able to move the software and data to a new laptop, but I didn't want the copy of Windows 7 to go to waste, so I did a P2V conversion by pulling out the hard drive, putting it in an external case, dd'ing the drive image, etc. I also saved the product key, just in case.

I ran it in VMware for a while, and then one day the screen turned black and I got "Get Genuine" messages every time I'd try to do anything. I tried to Get Genuine, over and over, but every time it failed, telling me to contact Acer. Attempts to Activate Windows just sent me to a Windows 10 FAQ.

No good!

For a long time, I tolerated the messages, but eventually called customer support to try to sort it out. I explained everything to them, and the fix was remarkably simple.

Open a command prompt and run:

slui 3

Then, enter the product key.

That's all.

At least on my side. What I don't know is whether they had to do something on their side too, to allow it.

Either way though, it was ultimately quite simple. So, if you've run into the same problem, try slui by itself, and if that doesn't work, call customer support and walk through it with them. They don't appear to just outright reject these kinds of activations because of the OEM key.

The only remaining problem was a black background. That was easily fixed by right-clicking on the desktop, selecting Personalize, and selecting the Windows 7 theme.

Good as new!