The host is an implementation detail
A business application gets installed on a server, and then the server slowly becomes part of the application. A scheduled task here. A COM component registered there. A mapped drive, a printer queue, a share, a registry value somebody set years ago for a reason nobody wrote down. None of it is in source control, because none of it is code.
Then support for the operating system ends, and moving a working application becomes a project nobody can scope. Not because the move is technically hard, but because nobody can say what would break. The only honest estimate is "we will find out".
In TSQL.APP the database is the application — the UI, the business logic, the permissions, all of it inside SQL Server. This post is about what follows from that, and it is the part people do not believe until they see it.
If the application is the database, everything outside the database is replaceable.
The framework's idea of "where am I"
An application is two databases. Your existing one holds your tables. A second one
holds the framework — the sp_api_* procedures and the api_* metadata that
describes cards, fields, buttons and permissions — and reaches your data through
synonyms.
Here is how the framework works out which pair it is running in. It is the entire multi-tenant model:
sqlDECLARE @proj_database nvarchar(128) = DB_NAME()
DECLARE @main_database nvarchar(128) = SUBSTRING(@proj_database,0,CHARINDEX('_proj',@proj_database,0))
EXEC sp_set_session_context 'main_database',@main_database
app_proj gives you app. That is the whole thing.
Read those three lines again and notice what is absent. No drive letter. No installation path. No machine name. No configuration file that has to be edited per environment. The framework's sense of place is derived entirely from the name of the database it happens to be executing in, and a database name is one of the few things that survives a move intact.
Everything above it inherits that property. A card that lists orders does not know which server it is on. An action script that posts an invoice does not know either. They could not find out if they wanted to — there is nothing in the programming surface that exposes it.
The obvious objection
At this point the reasonable assumption is that the move went well because the application was small. It is the other way round.
The application is large: years of accumulated business logic, hundreds of screens, the kind of system a company runs on and cannot pause. What is small is the part that had to be replaced. Those are different quantities, and almost every migration horror story comes from a stack where they are the same quantity.
The part that surprises people
Here is the mechanism, and it is structural rather than clever.
The framework never asks what it is running on, because the only layers that touch the operating system are the ones that hold no business logic.
Three things sit around the database, and none of them is allowed an opinion.
The API flattens every incoming HTTP request — whatever the verb, whatever the route — into a single four-column table and hands it to one stored procedure. It contains no domain knowledge at all. You can read the whole of it in an afternoon and learn nothing whatsoever about the business it serves, which is precisely the point.
The client renders whatever named result sets come back. It does not know what a purchase order is. It knows how to draw a list, a detail view and a modal, and it is told which to draw.
The worker performs the IO that SQL Server cannot do for itself — mail, HTTP, spreadsheets, PDFs, file transfers, printing — and is handed work through a queue.
So the surface that had to be ported was bounded before anyone started: two messengers and one limb, none of which knows anything. Port those and the application comes with them, unchanged, because the application was never in them.
The contrast worth holding on to is that in a conventional stack the platform-specific parts and the domain-specific parts are interleaved. A controller knows about both HTTP and invoices. A background job knows about both the file system and pricing. You cannot replace one without touching the other, so a platform migration becomes a code migration, and a code migration becomes a testing programme.
Here the line between them is a database boundary, enforced by the architecture rather than by discipline.
What that bought
TSQL.APP runs on SQL Server on Windows and on SQL Server on Linux, and the same application runs unchanged on either. Not recompiled, not ported, not forked — the same metadata and the same T-SQL.
We run production Solutions on Linux hosts today, and moving one there is a restore rather than a rewrite. The business logic never learns that anything happened.
That is the claim. The rest of this series is the machinery behind it, because the claim on its own is worth very little — anybody can say their software is portable. The next post is about the parts that genuinely did have to be rewritten, which turn out to have one thing in common: every one of them was something SQL Server had been doing outside the database.
There is documentation and a programming reference online, and you can always book a demo.