berlindb/core

A collection of PHP classes and functions that aims to provide an ORM-like experience and interface to WordPress database tables.

Maintainers

Package info

github.com/berlindb/core

pkg:composer/berlindb/core

Transparency log

Statistics

Installs: 457 061

Dependents: 7

Suggesters: 0

Stars: 270

Open Issues: 29

3.0.0 2026-05-28 15:32 UTC

This package is auto-updated.

Last update: 2026-07-16 23:50:08 UTC


README

CI Packagist Version PHP Version License

EDD Sugar Calendar WordPress WooCommerce

BerlinDB provides an ORM-like interface for custom database tables in WordPress.

Use it when custom post types, taxonomies, or post meta are no longer the right storage model for your data, but you still want a WordPress-native developer experience: wpdb compatibility, schema objects, query builders, row objects, caching hooks, and table upgrade routines.

Requirements

  • PHP 8.1 or newer
  • WordPress
  • Composer
  • MySQL 5.7+ or MariaDB 10.2+

BerlinDB generates MySQL/MariaDB-flavored SQL. The supported floor is MySQL 5.7 or MariaDB 10.2 (the baseline for the row-constructor IN and related SQL it emits); CI runs the suite against both engines at that floor and at a current release (MySQL 8.4, MariaDB 11.4). Older engines and other databases (PostgreSQL, SQLite, ...) are not supported.

Installation

composer require berlindb/core

Quick Start

A typical integration defines four small classes:

  • a Schema that describes columns and indexes
  • a Table that creates and upgrades the database table
  • a Row that shapes returned records
  • a Query that reads and writes records

Define A Schema

<?php

namespace Acme\Plugin\Database;

use BerlinDB\Database\Kern\Schema;

class WidgetSchema extends Schema {

	public $columns = array(
		array(
			'name'      => 'id',
			'type'      => 'bigint',
			'length'    => '20',
			'unsigned'  => true,
			'extra'     => 'auto_increment',
			'default'   => false,
			'cache_key' => true,
			'sortable'  => true,
		),
		array(
			'name'       => 'name',
			'type'       => 'varchar',
			'length'     => '200',
			'default'    => '',
			'searchable' => true,
			'sortable'   => true,
		),
		array(
			'name'      => 'status',
			'type'      => 'varchar',
			'length'    => '20',
			'default'   => 'active',
			'cache_key' => true,
			'in'        => true,
			'not_in'    => true,
		),
		array(
			'name'     => 'date_created',
			'type'     => 'datetime',
			'default'  => '',
			'created'  => true,
			'sortable' => true,
		),
	);

	public $indexes = array(
		array(
			'type'    => 'primary',
			'columns' => array( 'id' ),
		),
		array(
			'name'    => 'status',
			'type'    => 'key',
			'columns' => array( 'status' ),
		),
	);
}

Define A Table

<?php

namespace Acme\Plugin\Database;

use BerlinDB\Database\Kern\Table;

class WidgetTable extends Table {

	protected $schema = WidgetSchema::class;

	protected $name = 'acme_widgets';

	protected $version = '202605280';
}

Create or upgrade the table during your plugin's install or upgrade routine:

( new WidgetTable() )->install();

Define A Row

<?php

namespace Acme\Plugin\Database;

use BerlinDB\Database\Kern\Row;

class Widget extends Row {

	public $id = 0;

	public $name = '';

	public $status = 'active';

	public $date_created = '';
}

Define A Query

<?php

namespace Acme\Plugin\Database;

use BerlinDB\Database\Kern\Query;

class WidgetQuery extends Query {

	protected $prefix = 'acme';

	protected $table_name = 'widgets';

	protected $table_alias = 'w';

	protected $table_schema = WidgetSchema::class;

	protected $item_name = 'widget';

	protected $item_name_plural = 'widgets';

	protected $item_shape = Widget::class;

	protected $cache_group = 'acme-widgets';
}

Query Data

$query = new WidgetQuery();

$widget_id = $query->add_item(
	array(
		'name'   => 'Example',
		'status' => 'active',
	)
);

$widget = $query->get_item( $widget_id );

$active_widgets = $query->query(
	array(
		'status__in' => array( 'active', 'pending' ),
		'orderby'    => 'date_created',
		'order'      => 'DESC',
		'number'     => 20,
	)
);

$query->update_item(
	$widget_id,
	array(
		'status' => 'archived',
	)
);

$query->delete_item( $widget_id );

Documentation

The project wiki contains deeper documentation for the current object model, including adapters, interfaces, traits, parsers, operators, schemas, tables, and queries.

Development

Install dependencies:

composer install

Run the default test suite:

bin/run-tests.sh -- --group default

Run the suite against a specific PHP and WordPress version:

bin/run-tests.sh -p 8.1 -w 6.7 -- --group default

Run static analysis and coding standards:

vendor/bin/phpstan analyse --memory-limit=1G
vendor/bin/phpcs

See CONTRIBUTING.md for the full local workflow.

Name

BerlinDB is named for WordCamp Europe 2019 in Berlin, Germany, where it was originally exhibited and announced as an unnamed utility being used by the Sandhills Development engineering team.

Peter Wilson recommended naming it "Berlin" to commemorate everyone in attendance for its unveiling. Thanks, Peter.

License

BerlinDB is open-source software licensed under the MIT license.