atlas/table
Atlas.Table is a table data gateway for Atlas, providing a clean API to interact with database tables. Built to support Atlas.Mapper but usable on its own, it helps you run queries and persist table rows with a focused, lightweight design.
Installation:
composer require atlas/table
Ensure your project uses Atlas (e.g., atlasphp/atlas or atlasphp/atlas-mapper) for connection management.
Define a Table Class:
Extend Atlas\Table\Table and configure it for your database table:
use Atlas\Table\Table;
class UserTable extends Table
{
protected $table = 'users';
protected $primaryKey = 'id';
protected $columns = ['id', 'name', 'email', 'is_active'];
}
First Use Case: Fetch a Row
$userTable = new UserTable();
$user = $userTable->fetchRow(1); // Fetches row with id=1
echo $user->name; // Access columns directly
Key Entry Points:
fetchRow(), fetchRows(), insert(), update(), delete().TableEvents for hooks (e.g., beforeInsertRow()).Row objects for column iteration (foreach ($row as $column => $value)).Row Operations:
$row = $userTable->newRow(['name' => 'John', 'email' => 'john@example.com']);
$row->is_active = true;
$userTable->insert($row); // Triggers beforeInsertRow() event
$rows = [$userTable->newRow(['name' => 'Alice']), ...];
$userTable->insertRows($rows);
Querying:
$users = $userTable->select()->where('is_active', true)->fetchRows();
$select = new Atlas\Table\Select();
$select->from($userTable->getTable())
->where('name', 'LIKE', '%ohn%');
$users = $userTable->selectRows($select);
Event-Driven Logic:
use Atlas\Table\TableEvents;
class UserTableEvents implements TableEvents
{
public function beforeInsertRow($row): ?array
{
if (empty($row->email)) {
throw new \InvalidArgumentException('Email is required');
}
return $row->getArrayCopy(); // Return null to use default values
}
}
$userTable->setEvents(new UserTableEvents());
Row Iteration:
foreach ($user as $column => $value) {
echo "$column: $value\n";
}
// Or check modifications:
if ($user->isModified()) {
$userTable->update($user);
}
Laravel Database Connections:
Use Atlas’s ConnectionLocator to bridge Laravel’s DB facade:
$locator = new Atlas\ConnectionLocator();
$locator->addConnection('mysql', \DB::connection('mysql')->getPdo());
$userTable->setConnectionLocator($locator);
Composite Primary Keys:
Override getPrimaryKey() in your table class if using composite keys:
protected function getPrimaryKey(): array
{
return ['user_id', 'role_id'];
}
Type-Safe Selects:
Leverage _TableSelect classes for IDE autocompletion:
/** @var UserTableSelect */
$select = $userTable->select();
Primary Key Dependency:
updateRowPerform() and deleteRowPerform() throw exceptions if no primary key is defined (v1.4.0+).$primaryKey or override getPrimaryKey().Boolean Comparison Quirks:
Row::isModified() treats 1/0 as equivalent to true/false (v1.3.0+), but MySQL may still flag updates if the column is TINYINT(1).$row->is_active = (bool)$row->is_active;
Event Hook Signatures:
?array (v1.0.0-beta4+). Return null to use default values.void return types will fail.Identifier Quoting:
order). Use backticks explicitly:
$select->from('`order`');
Row Validation:
Row::assertValidValue() runs on construction, not assignment. To validate after changes:
$row->name = 'New Name';
$row->assertValidValue('name'); // Manual validation
Query Logging:
Enable Atlas’s query logging via ConnectionLocator:
$locator->setLogger(new \Atlas\Logger\QueryLogger());
Row Diffs:
Use getArrayDiff() to debug updates:
print_r($row->getArrayDiff()); // Shows modified columns
Event Debugging: Dump event payloads:
public function beforeInsertRow($row): ?array
{
\Log::debug('Inserting:', $row->getArrayCopy());
return $row->getArrayCopy();
}
Custom Row Classes:
Extend Atlas\Table\Row to add domain logic:
class UserRow extends \Atlas\Table\Row
{
public function getFullName(): string
{
return "{$this->first_name} {$this->last_name}";
}
}
Override Table::newRow() to return your class:
protected function newRow(array $data = []): UserRow
{
return new UserRow($this, $data);
}
Dynamic Columns:
Use getColumns() to fetch columns dynamically (e.g., from DB schema):
protected function getColumns(): array
{
return $this->getConnection()->fetchColumnNames($this->table);
}
Bulk Operations: Optimize bulk inserts/updates by batching rows:
$batch = [];
foreach ($users as $user) {
$batch[] = $user->getArrayCopy();
if (count($batch) >= 100) {
$userTable->insertRows($batch);
$batch = [];
}
}
No Eloquent Integration: Avoid mixing with Eloquent models. Use raw queries or Atlas.Mapper for hybrid setups.
Migration Conflicts: Atlas.Table assumes manual schema management. Use Laravel Migrations for schema changes, then sync with Atlas’s table definitions.
Testing:
Mock TableLocator and ConnectionLocator for unit tests:
$locator = $this->createMock(\Atlas\ConnectionLocator::class);
$locator->method('getConnection')->willReturn($pdo);
$userTable->setConnectionLocator($locator);
How can I help you explore Laravel packages today?