Skip to content

Instantly share code, notes, and snippets.

@dalabarge
Last active June 21, 2018 20:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dalabarge/56b2a0ec38e9c63619875a3ec3268f6f to your computer and use it in GitHub Desktop.
Save dalabarge/56b2a0ec38e9c63619875a3ec3268f6f to your computer and use it in GitHub Desktop.
A pgsql_send_query wrapper that integrates with Laravel's Eloquent models
<?php
$attributes = ['name' => 'John Doe'];
$query = User::where('email', 'john@example.com'); // $query->toSql() --> select * from `users` where `email` = ?
$grammar = $query->getQuery()->getGrammar();
$sql = $grammar->compileUpdate($query->getQuery(), $attributes); // update `users` set `name` = ? where `email` = ?
$bindings = $query->getBindings(); // ['john@example.com']
if( ! array_has($bindings, 'join') ) {
array_set($bindings, 'join', []); // because Grammar stupidly assumes a join binding
}
$bindings = $grammar->prepareBindingsForUpdate($bindings, $attributes); // ['John Doe', 'john@example.com']
$params = array_values(array_filter($bindings, function ($binding) {
return ! $binding instanceof \Illuminate\Database\Query\Expression;
}));
$replacements = [];
foreach($params as $i => $param) {
$sql = substr_replace($sql, '$'.($i+1), stripos($sql, '?'), 1);
}
// $sql === update `users` set `name` = $1 where `email` = $2
$config = config('database.connections.pgsql');
$connection = pg_connect(
sprintf('host=%s port=%d dbname=%s user=%s password=%s',
array_get($config, 'host'),
array_get($config, 'port'),
array_get($config, 'database'),
array_get($config, 'username'),
array_get($config, 'password')
));
if(! pg_send_query_params($connection, $sql, $params) ) {
throw new \Exception(pg_last_error($connection));
}
pg_close($connection);
// You could use DB::extend('pgsqlbg') to create a custom driver for `Connection`
// that accepts `update(string|Query|Model $query, array $bindings = [])` which
// would mask away the statement preparation details inside of the driver.
// Unfortunately there will be a lot of PDO assumptions which will need to be nooped.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment