Installation:
composer require conserto/pomm-foundation
Ensure ext-pgsql is enabled in your PHP configuration.
Basic Connection:
use PommProject\Foundation\SessionBuilder;
$session = (new SessionBuilder())
->withDsn('pgsql:host=localhost;dbname=your_db')
->build();
First Query:
$queryManager = $session->getClientUsingPooler('query_manager');
$result = $queryManager->getResult('SELECT * FROM users LIMIT 10');
foreach ($result as $row) {
print_r($row);
}
Type-Safe Data Handling:
// Convert PostgreSQL types to PHP objects/enums
$session->getClientUsingPooler('converter_holder')->registerConverter(
'your_enum_type',
new PgBackedEnum('your_enum_class')
);
// Use in a query
$queryManager->getResult('SELECT id, status FROM orders WHERE status = ?', ['active']);
SessionBuilder for pre-configured clients (e.g., query_manager, prepared_query).
$session = (new SessionBuilder())
->withDsn('pgsql:host=localhost;dbname=app')
->withOption('timezone', 'UTC')
->build();
$queryManager = $session->getClientUsingPooler('query_manager');
$result = $queryManager->getResult('SELECT * FROM products WHERE price > ?', [100]);
$preparedQuery = $session->getClientUsingPooler('prepared_query', 'SELECT * FROM users WHERE id = ?');
$result = $preparedQuery->execute([1]);
jsonb, hstore, citext).
$converterHolder = $session->getClientUsingPooler('converter_holder');
$row = $converterHolder->convertRow($result->fetch());
enum UserRole { Case('admin'), User('user') }
$converterHolder->registerConverter('user_role', new PgBackedEnum(UserRole::class));
$listener = $session->getClientUsingPooler('listener', 'channel_name');
$listener->listen(function ($payload) {
// Handle notification
});
use Illuminate\Support\ServiceProvider;
use PommProject\Foundation\SessionBuilder;
class PommServiceProvider extends ServiceProvider {
public function register() {
$this->app->singleton('pomm.session', function () {
return (new SessionBuilder())
->withDsn(config('database.connections.pgsql.dsn'))
->build();
});
}
}
Bind clients in boot():
$this->app->bind('pomm.query_manager', function ($app) {
return $app['pomm.session']->getClientUsingPooler('query_manager');
});
Configuration:
Add to config/database.php:
'pgsql' => [
'dsn' => env('DB_DSN', 'pgsql:host=localhost;dbname=laravel'),
'timezone' => env('DB_TIMEZONE', 'UTC'),
],
Query Builder Wrapper: Extend Laravel’s query builder to use Pomm:
use Illuminate\Database\Query\Builder;
use PommProject\Foundation\QueryManager;
class PommQueryBuilder extends Builder {
protected $queryManager;
public function __construct(QueryManager $queryManager) {
$this->queryManager = $queryManager;
}
public function get() {
$result = $this->queryManager->getResult($this->toSql(), $this->getBindings());
return $result->fetchAll();
}
}
prepared_query pooler.ResultIterator for large datasets:
$iterator = $queryManager->getIterator('SELECT * FROM large_table');
foreach ($iterator as $row) {
// Process row
}
FoundationSessionAtoum for test sessions:
use PommProject\Foundation\Tester\FoundationSessionAtoum;
class UserTest extends FoundationSessionAtoum {
protected function initializeSession($session) {
$session->getClientUsingPooler('converter_holder')->registerConverter(
'user_role',
new PommProject\Foundation\Converter\PgBackedEnum(UserRole::class)
);
}
}
Schema-Aware Composite Types:
ConvertedResultIterator fails to recognize custom composite types in non-public schemas (e.g., schema_name.type).pg_type queries.Timezone Mismatches:
timestamp conversion errors.->withOption('timezone', 'America/New_York')
Connection Leaks:
$session->shutdown() in Laravel’s terminating event:
Event::listen('terminating', function () {
if ($session = app('pomm.session')) {
$session->shutdown();
}
});
Enum Placeholders:
?) in WHERE IN clauses may fail with enums.$where = Where::createWhereIn('status', ['active', 'pending'], UserRole::class);
Hstore Parsing:
PgHstore::fromPg() with error handling:
try {
$hstore = PgHstore::fromPg($rawHstoreString);
} catch (InvalidArgumentException $e) {
// Handle error
}
Query Logging: Enable debug logging via PSR-3 logger:
$session->getClientUsingPooler('logger')->setLogger(new Monolog\Logger('pomm', [...]));
Result Inspection:
Use ResultInspector to debug raw PostgreSQL results:
$inspector = $session->getClientUsingPooler('inspector');
$inspector->inspect($result);
Converter Debugging: Check registered converters:
$converterHolder = $session->getClientUsingPooler('converter_holder');
print_r($converterHolder->getConverterNames());
Custom Converters:
Extend PommProject\Foundation\Converter\ConverterInterface:
class CustomTypeConverter implements ConverterInterface {
public function convertToPg($value) { /* ... */ }
public function convertFromPg($value) { /* ... */ }
}
Register with:
$converterHolder->registerConverter('custom_type', new CustomTypeConverter());
Query Managers:
Extend PommProject\Foundation\QueryManager\QueryManager to add custom methods:
class ExtendedQueryManager extends QueryManager {
public function customQuery($sql, $params) {
return $this->getResult($sql, $params);
}
}
Register with a custom pooler.
Session Middleware:
Use Session\SessionMiddleware to intercept session operations:
$session->addMiddleware(new class implements SessionMiddleware {
public function beforeExecute(Session $session, string $operation) { /* ... */ }
public function afterExecute
How can I help you explore Laravel packages today?