tdbengine
tdbengine is a tiny German relational database engine with a programming language, EASY, built into it: a single ~200 KB CGI executable that was both the script interpreter and the database, sold as an alternative to running PHP in front of MySQL. Its language descends from the macro dialect of Turbo-DataBase, a 1980s Pascal database toolbox from the German computer magazine CHIP, and its last public release was version 6.2.9 on 5 March 2004
Created by Ulrich Kern, described on the project's history page as the engine hacker behind the Windows-era Turbo-DataBase, working with Till Schwalm of CLS Verlagsbüro, who is credited with accompanying the TDB project from its birth. The whole line was published by tdb Software Service GmbH of Germany. The 99 Bottles of Beer entry for the language was contributed by Horst Klier, another member of the tdb team
tdbengine is a relational database management system with a programming language inside it. That language is called EASY, and the two are inseparable: you do not connect to tdbengine, you write your program in tdbengine, and the compiled result is a CGI executable that opens table files directly. The whole thing — interpreter, compiler, storage engine, B-tree indexer and full-text search — is described by the vendor as about 400 KB; the 2004 Linux release itself weighed 194,669 bytes.
It was made by a small German company, tdb software service GmbH, and it was sold with an unusually clear pitch: tdbengine is script language and database in one. In an era when the default answer to “dynamic website” was PHP talking to MySQL over a socket, tdbengine proposed that you skip both halves of that sentence.
Where it came from
The language is older than the engine. The vendor’s own history page traces an unbroken line back to 1985, when Turbo-DataBase (TDB) appeared as a database toolbox for Pascal developers, published in source form through the CHIP-Special series of the German computer magazine publisher Vogel Verlag. Over the following decade TDB grew from a toolbox into a fully relational, networked DOS database with — the page claims — 40,000 registered users. Macro programming arrived with TDB-4 1.1 in 1990; TDB-5 in 1991/92 was, in the vendor’s words, fully programmable; and by TDB 5.5 in 1994 the built-in language had a name, EASY.
Windows broke that world apart. The Turbo Database for Windows came out of a collaboration between the engine developer Ulrich Kern and the software house Pohmann & Partner, and became the Visual Data Publisher in 1996. But the DOS user base scattered, and tdbengine reads, in places, like an attempt to gather it back. The site’s Insider page is addressed directly at them:
Welcome our dear friends from the DOS-TDB era! […] All we want to do is compact, stable and fast software. And our philosophy is sought after on the internet. Whilst under Windows no software is taken serious weighing less than 300 MByte […] No one on the net can afford this. Here only speed and stability count — and we are right back at the virtues of Turbo-Database.
A TDB-Engine for internet work existed internally in 1997/98. tdbengine 6.0, in 1999, was the first public release with both the engine and an EASY interpreter and compiler. Version 6.2.4 in September 2000 ported it to Linux, FreeBSD and Win32; 6.2.7 in March 2002 made it freeware.
The language
EASY is procedural and modular, and its own documentation is candid about what that costs:
EASY is a historically grown language, so that not all of its language concepts open up as immediately as they would if it had been designed at the drawing board.
Lesson 4 of the introductory course places it “in the same category as C, Pascal or Modula”, and then lists the gaps: there is no way to define your own data types, there are no pointer types, and the only variables are simple scalars and multi-dimensional arrays over them. The scalars are REAL (8-byte float, 15–16 significant digits), INTEGER (32-bit), BYTE, CHAR, and STRING — a length-prefixed string whose single length byte caps it at 255 characters. Scoping has two levels and no more: declared inside a procedure is local, declared outside it is global.
Syntax is Pascal-flavoured with a peculiar layout rule inherited from the DOS macro language: reserved words originally had to begin their own line. The restriction was largely lifted in version 6.2.3, but the documentation goes on recommending it as a style. Comments start with //, with two dots, or run between /* and */. Identifiers are case-sensitive; keywords are not.
PROCEDURE Main
VAR nBottles : INTEGER
VAR s : STRING
CgiCloseBuffer
nBottles:=99
WHILE nBottles>=0
IF nBottles=1
s:=''
ELSE
s:='s'
END
CgiWriteLn(Str(nBottles)+' bottle'+s+' of beer on the wall,')
...
nBottles--
END
ENDPROC
That is the opening of the 99 Bottles of Beer program Horst Klier wrote on 3 June 2002 and submitted to 99-bottles-of-beer.net in April 2005 — the only sample of the language most programmers outside Germany ever saw. Note CgiCloseBuffer and CgiWriteLn: every tdbengine program is a CGI program, and its Main procedure is the entry point the web server calls.
The database is in the verbs
What makes EASY worth looking at is not its control flow but its vocabulary. There is no query language. Tables are opened, searched, marked and read with ordinary function calls:
VAR db : INTEGER = OpenDB('database/adressen.dat')
VAR nn : INTEGER = FindAndMark(db,'$PLZ LIKE "8????"')
IF nn=0 THEN
CGIWriteLn('Leider nichts gefunden')
ELSE
CGIWriteLn(Str(nn)+' Datensätze gefunden.')
VAR x : INTEGER = FirstMark(db)
WHILE x>0 DO
ReadRec(db,x)
CGIWriteLn(GetField(db,'Name'))
x:=NextMark(db,x)
END
END
The central abstraction is the marking list — a per-table bitmap of which rows a search hit, which you then walk with FirstMark/NextMark. Marking lists are first-class enough that the language has a TBITS array type for holding them, saving them to disk, and combining the results of two searches with BitAnd and BitOr. Alongside them sit GenIndex for B-tree indices over expressions such as '$1,$2', ScanRecs and MarkTable for building and searching a full-text index, and MakeDB for creating a table from a structure definition written as an INI-style text block.
Tables are files. Text files can be redirected into memory as ramtexts. Templates are HTML pages with placeholders, loaded with LoadTemplate — including over HTTP, through a proxy if HTTP_PROXY is set — which is how the project pursued what it called a strict isolation of web design from programming code.
The Hints for PHP developers page is the sharpest statement of how differently the thing wanted to be used. A tdbengine program is not a parsed HTML page; you do not write one script per action. You write one program with a dispatcher:
PROCEDURE Main
VAR command:=GetQueryString('command')
IF command='search' THEN ...
ELSIF command='login' THEN ...
ELSE ...
END
ENDPROC
Performance, with the caveats the vendor supplied
The project published a benchmark, and — refreshingly — published the disclaimer with it: Benchmarks need to be treated with care, since they use to measure only what the user wants it to measure. The numbers were produced by an EASY program whose full source was printed on the same page, run on the machine hosting the site, a Duron 700 under Linux 2.2.16, over 10,000 records with four string and four numeric fields. Creating the database took 1.35 seconds, building a B-tree index over the first two columns 0.33 seconds, and 10,000 indexed lookups 0.77 seconds. Building a complete full-text index took 4.97 seconds, and 100 wildcard full-text queries returning about 100 hits each took 5.95 seconds.
The page is equally willing to point at the bad result: filling an array with 40,000 random strings took 7.89 seconds, and the text concedes the engine “is not really fast regarding string-operations”, offering only that Perl has trouble there too because both use dynamic string management. These are early-2000s numbers on early-2000s hardware and mean nothing as a comparison against anything modern; what they show is the shape of the system, which was tuned for indexed retrieval and full-text search rather than for string churn.
In 2005 the company put the engine into an actual comparison, entering the database contest run by the German magazine c’t, which measured completed orders per minute against Dell’s DVD Store shop. tdb ported the PHP4/MySQL4 reference implementation one-for-one, reaching the data through EASY rather than SQL — and had to build a modified engine on the way, because the standard one could not read a query string longer than 255 characters.
The ecosystem, and what happened to it
For a few years around the middle of the decade there was a real community: a forum, an IRC channel on irc.tdbengine.org, a newsletter, syntax-highlighting files for Kate, Eclipse and UltraEdit, and an ecosystem of applications written in EASY — the eforia web manager CMS, the Bug-A-Boo bug tracker, wiki and forum hosting, a PDF library, and a mini HTTP server written in EASY so that a tdbengine application could run from a CD-ROM. tdbSQL, started in 2003, went the other way and tried to put a MySQL-compatible SQL server on top of tdbengine so that PHP, Perl, Java, C and Python clients could reach its tables. In July 2007 the shared library tdblib and the utility collection eforia-base were released under the GPL; in August 2007 the Tdbengine Application Server was opened up too.
The engine itself never followed. Version 6.2.7 was declared freeware in 2002 with a stated intention to move to the GPL “in the foreseeable future”, and nothing in the record shows that ever happening. The download page stopped changing in March 2004. It was still there, still offering 6.2.9, when the Internet Archive looked in September 2018 — fourteen years of a website that had simply stopped. By 2021 tdbengine.org served only a corporate page; by 2024 the domain had been sold on and now hosts an Indonesian gambling site.
Where it stands
tdbengine did not die; it went behind a paywall and stopped talking. tdb software service GmbH is still trading, and its current site still opens the Was ist tdb? page with the same sentences it used in 2004: an RDBMS with the integrated programming language EASY, about 400 KB, versions for Linux, FreeBSD and Windows. But one sentence has been added — the engine has not been distributed as freeware since version 6.04.03 — and the company now sells managed hosting for EASY applications from 50 to 1,499 euro a month, promising continuous updates of the engine to those customers. Somewhere behind that offer, a language whose ancestry runs back to a Pascal toolbox printed in a 1985 magazine special is still being compiled and run.
Why it matters
tdbengine is a good specimen of a design that the LAMP stack made unfashionable and that has quietly come back: put the database in the process. A tdbengine CGI program opens its tables as files, in its own address space, with no server, no socket, no connection pool and no query parser between the program and the B-tree — the same bet, in a different decade and a different key, that SQLite, LMDB, DuckDB and every other embedded engine makes. The vendor’s argument for it was exactly the argument made for embedded databases now: direct access is faster, and a 200 KB binary you can copy into a cgi-bin directory is easier to deploy than a database server you have to administer.
It is also a reminder of how much of programming history is written in languages that never left one country. EASY has been named in the vendor’s release history since 1994, on a product line that vendor traces back to 1985, and the DOS product it grew out of reportedly had 40,000 registered users at its peak. It has a full course, a function reference, a benchmark suite and a working SQL layer — and almost all of that exists only in German, only on a website that no longer exists, and reachable now only through the Internet Archive. The one artefact that made it into the international record is a short program about beer.
Timeline
Notable Uses & Legacy
tdb software service GmbH hosting
The vendor's own business. Its current site sells four tiers of managed hosting for customer applications written in EASY, running on servers it says are kept in the company building with no service other than tdbengine installed on them, and it commits to keeping the engine updated for those customers - which is why the engine is still maintained four decades after the Pascal toolbox it grew out of
Tdbengine Application Server (TAS)
An open-source framework built entirely in EASY, announced on the project blog in August 2007 after nearly two years of internal use in large customer projects. It supplied user and session handling, marking-list management and job scheduling, allowed EASY to be embedded in HTML pages instead of written as standalone modules, and shipped widgets that drove the Dojo Toolkit from the server side
eforia web manager and Bug-A-Boo
The two applications the project used to advertise itself: a commercial web content-management system and an open-source bug tracker, both written in EASY on top of tdbengine. The download page also linked to free wiki, forum and hosting services running on the same engine
tdbSQL
A SourceForge project started in 2003 by tdb employee Thomas Friebel to build a MySQL-like SQL server on top of tdbengine, so that PHP, Perl, Java, C and Python clients could reach tdbengine tables. It included an EASY client library, easysql.mod, letting one tdbengine program query another over the network with an ordinary connect/query/disconnect API
The c't database contest entry (2005)
tdb ported Dell's DVD Store benchmark shop - the reference implementation of which was written for PHP4 and MySQL 4 - to tdbengine for a comparison run by the German magazine c't, measuring completed orders per minute. The port used a full-text index over two columns of the products table and heavily compressed code, with whole HTML forms emitted from single cgiwriteln() calls