Search by

minosuko / foxydb-serverless

Minosuko

There is no license information available for the latest version (dev-main) of this package.

Embedded, serverless FoxyDB for PHP applications

Package info

github.com/Minosuko/FoxyDB-serverless

pkg:composer/minosuko/foxydb-serverless

Statistics

Installs: 0

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

dev-main 2026-07-24 07:56 UTC

This package is auto-updated.

Last update: 2026-08-24 08:10:44 UTC


README

FoxyDB Serverless embeds the FoxyDB SQL and storage engines directly in a PHP process. It needs no daemon, port, TLS certificate, username, or password. Data is durable after each successful write and can be reopened by another process.

This is an early embedded implementation. Test it with representative workloads and maintain backups before using it for important data.

Requirements

  • 64-bit PHP 8.2 or newer
  • json, mbstring, and zlib PHP extensions
  • A local filesystem with working advisory file locks

Open And Query

For a repository checkout, load the serverless autoloader:

<?php

require __DIR__ . '/serverless/src/Autoloader.php';

use FoxyDB\Embedded\Database;

$db = Database::open(__DIR__ . '/application.foxydb');
$db->query(
    'CREATE TABLE IF NOT EXISTS users ('
    . 'id BIGINT PRIMARY KEY AUTO_INCREMENT, '
    . 'email VARCHAR(255) NOT NULL UNIQUE, '
    . 'created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP'
    . ')'
);

$insert = $db->query('INSERT INTO users (email) VALUES (?)', ['fox@example.test']);
echo $insert->lastInsertId . PHP_EOL;

$users = $db->query('SELECT id, email FROM users ORDER BY id');
foreach ($users as $user) {
    echo $user['email'] . PHP_EOL;
}

$db->close();

query() uses positional ? or named :name parameters. Returned QueryResult objects are materialized, repeatable, iterable, and countable. BLOB and BINARY values are returned as FoxyDB\Value\BinaryValue; text values are returned as strings.

Database Bundle

The path passed to Database::open() is an opaque bundle directory, even when it ends in .foxydb:

application.foxydb/
  embedded.meta
  embedded.lock
  catalog.lock
  databases/
  locks/

The current FoxyDB engine stores table generations, indexes, locks, and content-addressed chunks as separate files. It therefore does not claim to be a single-file format. Passing a regular file or an unmarked nonempty directory fails without replacing its contents.

An embedded bundle has one automatically selected database named main. CREATE DATABASE, DROP DATABASE, and USE for any other name are rejected. Tables can be used immediately after opening the bundle.

Options

use FoxyDB\Embedded\Database;
use FoxyDB\Embedded\Options;

$db = Database::open(
    __DIR__ . '/application.foxydb',
    new Options(
        syncWrites: true,
        chunkBytes: 1_048_576,
        inlineValueBytes: 65_536,
        maxMaterializedBytes: 67_108_864,
        maxRowsPerResult: 1_000_000,
    ),
);

syncWrites: false can improve write throughput but weakens power-loss durability. The materialization and row limits bound each returned result. Large values remain chunked on disk and are materialized only when selected.

Concurrency And Durability

Multiple PHP handles and processes may open the same local bundle. FoxyDB coordinates catalog, table, and row publication with advisory file locks. Writes are visible before close(); closing a handle is not a commit operation.

Do not place a bundle on a filesystem that does not provide reliable local flock() semantics. For a consistent filesystem-level backup, stop writes and close all handles before copying the entire bundle directory.

SQL And Boundaries

Embedded mode supports the same table, index, insert, select, update, delete, compaction, parameter, type, and predicate syntax documented in FoxyDB-server/README.md.

Embedded mode removes the network and authentication layers; it does not add SQL features missing from the engine. Transactions, joins, grouping, subqueries, replication, and ALTER TABLE are not currently implemented. A multi-row operation can commit a recoverable prefix if an operating-system or disk failure interrupts it.

Tests

From this directory:

php tests/run.php

The suite covers persistence, simultaneous handles, large text and binary values, resource limits, path safety, lifecycle behavior, and co-loading with the TCP client library.