PHPackages                             daycry/schemas - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Database &amp; ORM](/categories/database)
4. /
5. daycry/schemas

ActiveLibrary[Database &amp; ORM](/categories/database)

daycry/schemas
==============

Database schema management, for CodeIgniter 4

v2.0.0(9mo ago)1981MITPHPPHP ^8.1CI failing

Since Aug 28Pushed 9mo ago1 watchersCompare

[ Source](https://github.com/daycry/schemas)[ Packagist](https://packagist.org/packages/daycry/schemas)[ Docs](https://github.com/daycry)[ RSS](/packages/daycry-schemas/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (3)Dependencies (8)Versions (4)Used By (1)

Schemas (Minimal Core) for CodeIgniter 4
========================================

[](#schemas-minimal-core-for-codeigniter-4)

[![Build status](https://github.com/daycry/schemas/actions/workflows/php.yml/badge.svg?branch=master)](https://github.com/daycry/schemas/actions/workflows/php.yml)[![Coverage Status](https://camo.githubusercontent.com/ed3b1766e88a422f6ed08069bf1b003016051561b9fcac07f67553511d93e5ca/68747470733a2f2f636f766572616c6c732e696f2f7265706f732f6769746875622f6461796372792f736368656d61732f62616467652e7376673f6272616e63683d6d6173746572)](https://coveralls.io/github/daycry/schemas?branch=master)[![Downloads](https://camo.githubusercontent.com/158fe576921697d3eada1851cd2225fe3926a9bd36a17f151b998a2593cb5afc/68747470733a2f2f706f7365722e707567782e6f72672f6461796372792f736368656d61732f646f776e6c6f616473)](https://packagist.org/packages/daycry/schemas)[![GitHub release (latest by date)](https://camo.githubusercontent.com/6161cd2a3196b62b9ba1fd3c394046299ce993e51ccd53885f92b8cfaee6ca6a/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f762f72656c656173652f6461796372792f736368656d6173)](https://packagist.org/packages/daycry/schemas)[![GitHub stars](https://camo.githubusercontent.com/1c673f9ec4b8bb1112252b42b2cf2c4ffecbf74ead07a72f4b455a91c2a244ef/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f73746172732f6461796372792f736368656d6173)](https://packagist.org/packages/daycry/schemas)[![GitHub license](https://camo.githubusercontent.com/2087f42b082952423f4b46975bf40dd2fcb6741f6cbe6c5e7cb857bf38f7885c/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6963656e73652f6461796372792f736368656d6173)](https://github.com/daycry/schemas/blob/master/LICENSE)

> Minimal core edition: focused only on drafting (database / model / directory), reading, and archiving (cache). Async, plugins, events, layered environments, complex validation, advanced relation flags, and export/import formats were removed for a lean runtime.

Quick Start
-----------

[](#quick-start)

1. Install with Composer: `composer require daycry/schemas`
2. Generate and cache a schema (database + models) via spark: `php spark schemas -draft database,model -archive cache`
3. Fetch it (try cache first, draft if missing): ```
    $schemas = service('schemas');
    $schema  = $schemas->load()->get(); // load() attempts cache (if archived previously)
    if (! $schema) {
         $schemas->draft()->archive('cache');
         $schema = $schemas->get();
    }
    ```

Core Feature Summary
--------------------

[](#core-feature-summary)

- Database structure introspection (tables, fields, indexes, foreign keys)
- Draft sources: database, models, directory (user-provided PHP schema files)
- Archive + read from cache (file/redis/etc via CI4 cache handlers)
- Lightweight structure objects: Schema, Table, Field, Index, ForeignKey, Relation
- Simple automation flags (draft / archive / read)
- Explicit, extensible handler lists (swap or extend by config)

Removed Legacy Subsystems
-------------------------

[](#removed-legacy-subsystems)

Removed FeatureWhyReplacement / PathAsync background draftingComplexity &gt; benefitRun synchronously (fast)Plugin managerIndirection overheadCreate small wrapper packagesEvent busRare real useAdd domain events externally if neededExport/Import (json/php/yaml)Serialization bloatFuture addon (see Extensions)Snapshot/runtime overridesHidden mutable stateExplicit service instancesLayered environment profilesHard to reasonSingle flat config classValidation engineRedundant vs testsRely on types + PHPUnitLogging / metrics collectorUnnecessary core weightUse app/logger directlyAdvanced relation flagsToo many togglesSingle boolean `$relationships`If you relied on something removed, create a thin external package that composes over this core.

Installation
------------

[](#installation)

Composer (recommended):

```
composer require daycry/schemas

```

Manual: clone/download and add the `src` namespace to your `app/Config/Autoload.php`.

Configuration
-------------

[](#configuration)

Publish (optional) configuration to your app (if a publisher command is present) or copy the distributed template to `app/Config/Schemas.php`.

Key options (see `src/Config/Schemas.php`):

```
public string $defaultGroup = 'default';        // Database group
public array  $ignoredTables = ['migrations'];  // Skip these tables
public array  $includedTables = [];             // If non-empty: only these tables
public string $tablePrefix = '';                // Add/remove prefix handling
public bool   $silent = true;                   // Best-effort mode
public array  $cache = [                        // Archive/read cache config
    'enabled' => false,
    'handler' => 'file',
    'ttl'     => 3600,
    'prefix'  => 'schemas_',
];
public bool $relationships = true;              // Auto relation detection
public array $automate = [                      // Auto actions when needed
    'draft' => true,
    'archive' => true,
    'read' => true,
];
public array $draftHandlers = [                 // Order-sensitive
    'database'  => DatabaseHandler::class,
    'model'     => ModelHandler::class,
    'directory' => DirectoryHandler::class,
];
public array $archiveHandlers = [               // Archive modes
    'cache' => CacheHandler::class,
];
public array $readHandlers = [                  // Reader sources
    'cache'     => \Daycry\Schemas\Reader\Handlers\CacheHandler::class,
    'directory' => \Daycry\Schemas\Reader\Handlers\DirectoryHandler::class,
    'php'       => \Daycry\Schemas\Reader\Handlers\PhpHandler::class,
    'json'      => \Daycry\Schemas\Reader\Handlers\JsonHandler::class,
];
```

Edit handler lists to extend or swap implementations.

Public API Surface
------------------

[](#public-api-surface)

The intent is a small, explicit contract. Everything not listed here should be considered internal and subject to change between minor versions.

### Service: `Daycry\Schemas\Schemas`

[](#service-daycryschemasschemas)

Workflow (chainable) methods:

- `draft(array|string|null $handlers = null): self` – Merge drafted structures from one or more handler keys or class names. Null = all configured draft handlers in order.
- `archive(string|array $mode = 'cache'): self` – Persist the current schema using configured archive handler(s) for a mode, or pass an array of archiver instances.
- `read(string|array $path): self` – Load schema data from cache/directory/php/json sources and merge.

State helpers:

- `get(): ?Schema` – Current in-memory schema (or `null`). Does NOT perform I/O.
- `load(): ?Schema` – Attempt to load from cache if not already loaded; returns the schema or `null`.
- `setSchema(Schema $schema): self` – Replace current schema.
- `reset(): self` – Clear schema &amp; errors.
- `getErrors(): string[]` – Retrieve &amp; clear collected errors.

### Structures (`Daycry\Schemas\Structures`)

[](#structures-daycryschemasstructures)

Plain data objects (all final except `Mergeable` base):

- `Schema`, `Table`, `Field`, `Index`, `ForeignKey`, `Relation`, plus additional DB objects if present (e.g., Procedure, Trigger, View).

### Draft Handlers (`Daycry\Schemas\Drafter\Handlers`)

[](#draft-handlers-daycryschemasdrafterhandlers)

- `DatabaseHandler` – Introspects DB schema via configured database group.
- `ModelHandler` – Parses application Models for table/field hints.
- `DirectoryHandler` (+ sub-handlers like `DirectoryHandlers\PhpHandler`) – Loads user-provided schema PHP files.

### Archive Handlers (`Daycry\Schemas\Archiver\Handlers`)

[](#archive-handlers-daycryschemasarchiverhandlers)

- `CacheHandler` – Stores schema in CodeIgniter Cache.

### Reader Handlers (`Daycry\Schemas\Reader\Handlers`)

[](#reader-handlers-daycryschemasreaderhandlers)

- `CacheHandler`, `DirectoryHandler`, `PhpHandler`, `JsonHandler` – Rehydrate schema from respective sources.

### Extensibility Points

[](#extensibility-points)

- Add a new draft handler: implement `DrafterInterface`, register in `$draftHandlers`.
- Add an archive handler: implement `ArchiverInterface`, add to `$archiveHandlers` list or new mode key.
- Add a reader: implement `ReaderInterface`, map extension/key in `$readHandlers`.
- Provide custom static schema slices: place PHP schema files in your configured `schemasDirectory`.

Usage
-----

[](#usage)

Basic automated workflow (all automate flags true):

```
$schemas = service('schemas');
$schema = $schemas->get(); // Will auto draft/read/archive on first call depending on flags
```

Manual workflow control:

```
$schemas = service('schemas');

// Draft database + models then archive
$schemas->draft(['database','model'])->archive();

// Later, read from cache, add directory schemas, and fetch
$schema = $schemas->read('cache')->draft('directory')->get();
```

Custom handler instance:

```
$db = db_connect('alternate');
$schemas = service('schemas');
$databaseHandler = new \Daycry\Schemas\Drafter\Handlers\DatabaseHandler(config('Schemas'), $db);
$schema = $schemas->draft([$databaseHandler])->get();
```

Command
-------

[](#command)

Spark command to draft &amp; archive or print schemas:

```
php spark schemas -draft database,model -archive cache
php spark schemas -draft database,model,directory -print

```

Flags:

- `-draft handler1,handler2` (optional; default = all configured)
- `-archive cache` (or omit to skip archiving)
- `-print` output current schema to console (bypasses archive)

Automation
----------

[](#automation)

`$automate` can be used (if enabled) to mimic legacy behavior (auto draft/read/archive). In the minimal core you are encouraged to call the methods you need explicitly. The provided `load()` method offers a lightweight manual cache check pattern. Disable flags you do not want executed implicitly.

Recommended explicit flow:

```
$schemas = service('schemas');
if (! $schemas->load()) {            // null => nothing in cache
    $schemas->draft()->archive();    // build & store
}
$schema = $schemas->get();           // schema now present
```

Relationships, Foreign Keys &amp; Lazy Tables
---------------------------------------------

[](#relationships-foreign-keys--lazy-tables)

Drafting from the database collects tables, fields, indexes and foreign keys. Relationships are inferred (when `$relationships = true`) using:

- Real foreign keys (preferred)
- Pivot table heuristics: table with only two foreign key columns referencing distinct tables → many-to-many
- Column naming pattern: `{other_table}_id` → belongsTo/hasMany guess (fallback)

### Lazy Table Placeholders (Cache)

[](#lazy-table-placeholders-cache)

When archiving to cache, the `CacheHandler` stores a scaffold: each table slot becomes `tableName => true` and the full `Table` object is saved under a separate cache key. This minimizes the size of the main schema entry and defers hydration.

How to materialize:

```
$schemas->load();              // scaffold only (tables => true)
$schema = $schemas->get();

// Access one table (lazy load via reader magic)
$users = $schema->tables->users; // now users is a Table object

// Or fetch all tables eagerly if reader supports it
if (is_object($schema->tables) && method_exists($schema->tables, 'fetchAll')) {
    $schema->tables->fetchAll();
}
```

### Foreign Keys of a Table

[](#foreign-keys-of-a-table)

```
$posts = $schema->tables->posts;         // lazy hydrate
foreach ($posts->foreignKeys as $name => $fk) {
    echo $fk->column_name, ' -> ', $fk->foreign_table_name, '.', $fk->foreign_column_name, PHP_EOL;
}
```

If a table still shows as `true`, call:

```
$schema->tables->fetch('posts');
```

### Intervention / Manual Adjustments

[](#intervention--manual-adjustments)

- **Config/Schemas**: Use `$ignoredTables` to skip noisy tables.
- **app/Schemas/\*.php**: Provide overrides or custom additions (DirectoryHandler). Example: [tests/\_support/Schemas/Good/Products.php](tests/_support/Schemas/Good/Products.php).

Supported Draft / Archive / Read
--------------------------------

[](#supported-draft--archive--read)

Draft: `database`, `model`, `directory`

Archive: `cache`

Read: `cache`, `directory`, `php`, `json`

Database Support
----------------

[](#database-support)

All CodeIgniter 4 database drivers work but due to some differences in index handling they may not all report the same results. Example: see skipped tests for SQLite3.

Extensions &amp; Addons
-----------------------

[](#extensions--addons)

You can prototype external addons without modifying core by creating packages that:

- Provide new handler classes (implement the appropriate interface)
- Recommend a config snippet for users to append handlers
- (Optionally) add a spark command for export or diagnostics

Example add‑ons (future packages):

- `daycry/schemas-export-json` – export/import JSON
- `daycry/schemas-events` – lightweight event dispatcher wrapper

Roadmap (Minimal Core Perspective)
----------------------------------

[](#roadmap-minimal-core-perspective)

Potential future (only if demanded by real-world use):

- External export/import addon(s)
- Optional tiny event hook layer
- Migration diff generation as standalone tool

PRs welcome – keep the core surface area minimal.

###  Health Score

35

—

LowBetter than 77% of packages

Maintenance58

Moderate activity, may be stable

Popularity13

Limited adoption so far

Community9

Small or concentrated contributor base

Maturity51

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~199 days

Total

3

Last Release

276d ago

Major Versions

v1.0.1 → v2.0.02025-09-30

### Community

Maintainers

![](https://www.gravatar.com/avatar/3b0f66565d5c9ca3c84fb294e04f8d5e0b9a867d9c06f83b95bf168bd6fcf9bc?d=identicon)[daycry](/maintainers/daycry)

---

Top Contributors

[![daycry](https://avatars.githubusercontent.com/u/7590335?v=4)](https://github.com/daycry "daycry (23 commits)")

---

Tags

databasecodeignitermappingstructurecodeigniter4schemas

###  Code Quality

TestsPHPUnit

Code StylePHP CS Fixer

Type Coverage Yes

### Embed Badge

![Health badge](/badges/daycry-schemas/health.svg)

```
[![Health](https://phpackages.com/badges/daycry-schemas/health.svg)](https://phpackages.com/packages/daycry-schemas)
```

###  Alternatives

[tatter/schemas

Database schema management, for CodeIgniter 4

2330.4k1](/packages/tatter-schemas)[propel/propel1

Propel is an open-source Object-Relational Mapping (ORM) for PHP5.

8351.6M87](/packages/propel-propel1)[tatter/relations

Entity relationships for CodeIgniter 4

8924.1k1](/packages/tatter-relations)[codeigniter4/queue

Queues for CodeIgniter 4 framework

71210.3k5](/packages/codeigniter4-queue)[michalsn/codeigniter-queue

Queues for CodeIgniter 4 framework

714.1k](/packages/michalsn-codeigniter-queue)[concretecms/doctrine-xml

Define database structure via XML using Doctrine data types

11117.6k4](/packages/concretecms-doctrine-xml)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
