article thumbnail
WaSQL
The database-driven web framework
10 min read
#php, #wasql, #ajax, #databases, #framework, #webdevelopment, #friday4

WaSQL: Key Concepts

WaSQL is a database-driven PHP framework built for operational simplicity and developer velocity. While other frameworks require complex deployment pipelines, multiple tools, and specialized knowledge, WaSQL puts everything - code, deployment, monitoring, and ETL - in one place.

Why WaSQL?

The Problem with Traditional Frameworks

Modern web frameworks are powerful, but they come with operational overhead:

The WaSQL Approach

WaSQL solves these problems by storing everything in the database - not just your data, but your application code, templates, and configuration. This seemingly unconventional design choice enables powerful capabilities:

Instant Deployment
Export your entire application as a MySQL dump. Import it anywhere. Your code, logic, templates, and data move together as a unit.

Built-in Version Control
Visual diffs show exactly what changed between environments. Built-in sync tools let you push changes from dev to stage to production, or revert from production back to dev. Optional code review workflows require a second developer to approve changes before deployment.

Unified Platform
ETL pipelines, cron job management, user authentication, and application code all live in one system. No need to cobble together separate tools.

Operational Simplicity
Runs on a single server. No distributed systems, no Kubernetes, no specialized expertise required. Any PHP developer can understand and maintain it.

Battle-Tested at Scale
WaSQL runs production systems processing millions of records daily, managing thousands of concurrent cron jobs, and integrating multiple enterprise databases. In one case, it replaced a failed Kafka implementation at a billion-dollar company and was rebuilt from scratch in under two weeks.

How WaSQL Works

Pages as Database Records

In WaSQL, there are no "page files" to upload. Each page is a record in the _pages table with these fields:

This design makes applications portable, version-controllable through the database, and deployable with built-in sync tools.

Routing with $PASSTHRU

WaSQL uses the $PASSTHRU array for clean URL routing:

global $PASSTHRU;
switch(strtolower($PASSTHRU[0])){
    case 'list':
        setView('list',1);
        return;
        break;
    case 'addedit':
        $id = $PASSTHRU[1];
        setView('addedit',1);
        break;
    default:
        setView('default');
        break;
}

No separate routes file needed - routing logic lives right in the controller.

Views in the Body Field

Views are written directly in the body field using named view blocks:

<view:default>
    <h1>Hello World</h1>
    <a href="#" data-div="main_content" data-nav="/t/1/mypage/list" 
       onclick="return wacss.nav(this);">
        Load Users
    </a>
    <div id="main_content"></div>
</view:default>

<view:list>
    <?=mypageList();?>
</view:list>

<view:addedit>
    <div><?=mypageAddedit($id);?></div>
</view:addedit>

<view:addedit_fields>
    <div style="display:flex;flex-wrap: wrap;gap:10px;">
        <div><label>Firstname</label>[firstname]</div>
        <div><label>Lastname</label>[lastname]</div>
    </div>
    <div><label>Email Address</label>[email]</div>
</view:addedit_fields>

The controller calls setView() to determine which view block to display. WaSQL automatically loads the default view if no explicit setView() is called.

Functions: Your Application Logic

The functions field contains reusable helper functions that are called from controllers or views:

<?php
function mypageList(){
    $opts=array(
        '-table'=>'_users',
        '_id_options'=>array(
            'data-div'=>'centerpop',
            'data-nav'=>'/t/1/mypage/addedit/%_id%',
            'onclick'=>"return wacss.nav(this);"
        )
    );
    return databaseListRecords($opts);
}

function mypageAddedit($id=0){
    $opts=array(
        '-table'=>'_users',
        '-fields'=>getView('addedit_fields')
    );
    // Go into edit mode if $id is not zero
    if($id > 0){
        $opts['_id']=$id;
    }
    return addEditDBForm($opts);
}
?>

WaSQL provides powerful helper functions like databaseListRecords() that generate full list views with sorting, pagination, and actions, and addEditDBForm() that automatically creates forms and handles add/edit operations.

Database Operations Made Simple

WaSQL abstracts SQL entirely with intuitive helper functions:

// Fetch users with sorting and limit
$users = getDBRecords([
    '-table'=>'_users',
    '-order'=>'name',
    'limit'=>50
]);

// Retrieve a single record by ID
$rec = getDBRecordById('_users', 54);

// Add a new user
$id = addDBRecord([
    '-table' => '_users',
    'name' => 'John Doe'
]);

// Update a user
$ok = editDBRecordById('_users', $newId, [
    'email' => 'john@example.com'
]);

// Generate a complete add/edit form
$opts = ['-table'=>'test'];
return addEditDBForm($opts);

Everything returns associative arrays (not objects), making it easy to pass data into views or convert to JSON for JavaScript.

Development Workflow

PostEdit: Database ↔ File Sync

While your code lives in the database, you can still use your favorite IDE. PostEdit monitors local files and automatically updates database records when files change.

Use the p.bat alias to sync database records to local files, edit them in your IDE, and PostEdit will push changes back to the database. It includes conflict detection - if another developer changed a record after you pulled it, PostEdit prevents your change and alerts you.

Environment Synchronization

WaSQL's built-in sync tools let you:

  1. Compare environments - View diffs between dev, stage, and production
  2. Review changes - See exactly what changed in each record with syntax-highlighted diffs
  3. Push selectively - Deploy only the tables/records you want
  4. Require approval - Optionally require a second developer to review before pushing
  5. Revert quickly - Pull changes from production back to dev for instant rollback

This replaces Git, CI/CD pipelines, and deployment scripts with a unified, visual workflow.

Multi-Language Support

WaSQL is written in PHP but also supports embedded Python, Perl, Lua, R, Tcl, and Node.js. Global variables like $_REQUEST, $_SESSION, $_SERVER, $CONFIG, and $USER are available to all languages. You can even code in multiple languages on a single page.

Enterprise ETL

WaSQL excels at data integration, supporting:

Built-in cron management with visual monitoring makes it ideal for ETL pipelines. View active jobs, memory usage, execution logs, and scheduling all from the admin interface.

Who Should Use WaSQL?

Ideal for:

Not ideal for:

Getting Started

WaSQL's design may seem unconventional, but it's optimized for what matters most: building applications quickly, deploying them reliably, and maintaining them easily over time. The database-centric approach that seems limiting at first becomes liberating once you embrace it.

Everything is in one place. Everything is queryable. Everything is deployable. Everything just works.

Ready to learn more? Check out the Advanced Concepts guide for deployment workflows, scaling strategies, and production best practices.