* requires PHP module "pgsql" (Debian package name "php-pgsql") */ class struct_subject_postgresql { /** * @var string * @author Christian Fraß */ public $host; /** * @var int * @author Christian Fraß */ public $port; /** * @var string * @author Christian Fraß */ public $schema; /** * @var string * @author Christian Fraß */ public $username; /** * @var string * @author Christian Fraß */ public $password; /** * @author Christian Fraß */ public function __construct( string $host, int $port, string $schema, string $username, string $password ) { $this->host = $host; $this->port = $port; $this->schema = $schema; $this->username = $username; $this->password = $password; } } /** * @author Christian Fraß */ function postgresql_make( string $host, int $port, string $schema, string $username, string $password ) : struct_subject_postgresql { return ( new struct_subject_postgresql( $host, $port, $schema, $username, $password ) ); } /** * @return string * @author Christian Fraß */ function postgresql_terminal_autoincrement( ) : string { return 'AUTO_INCREMENT'; } /** * @return string * @author Christian Fraß */ function postgresql_boilerplate_field_definition_for_integer_primary_key_with_auto_increment( ) : string { return 'SERIAL PRIMARY KEY'; } /** * @param struct_subject_postgresql $subject * @param string $template * @param array $arguments * @return array * @author Christian Fraß */ function postgresql_query( struct_subject_postgresql $subject, string $template, array $arguments ) : array { $connection = \pg_connect( sprintf( 'host=%s port=%d user=%s password=%s dbname=%s', $subject->host, $subject->port, $subject->username, $subject->password, $subject->schema ) ); // \pg_set_client_encoding($connection, \UNICODE); \pg_query($connection, "SET client_encoding TO 'UNICODE'"); $template_adjusted = $template; $arguments_adjusted = []; $counter = 0; foreach ($arguments as $key => $value) { $pattern = \sprintf(':%s', $key); $replacement = \sprintf('$%d', $counter+1); $counter += 1; $template_adjusted = str_replace($pattern, $replacement, $template_adjusted); \array_push($arguments_adjusted, $value); } $report = \alveolata\report\make( 'postgresl_query', [ 'template' => $template_adjusted, 'arguments' => $arguments, ] ); \alveolata\log\debug_($report); $result = \pg_query_params($connection, $template_adjusted, $arguments_adjusted); if ($result === false) { $report = \alveolata\report\make( 'postgresl_query_failed', [ 'template' => $template_adjusted, 'arguments' => $arguments_adjusted, ] ); throw (\alveolata\report\as_exception($report)); } else { // $status = \pg_result_status($result, \PGSQL_STATUS_STRING); $status = \pg_result_status($result, \PGSQL_STATUS_LONG); switch ($status) { default: { $report = \alveolata\report\make( 'postgresl_query_bad_result', [ 'template' => $template_adjusted, 'arguments' => $arguments_adjusted, 'status' => $status, ] ); throw (\alveolata\report\as_exception($report)); break; } case \PGSQL_COMMAND_OK: case \PGSQL_TUPLES_OK: { $id_raw = \pg_last_oid($result); return [ 'rows' => \pg_fetch_all($result, \PGSQL_ASSOC), 'id' => (($id_raw === false) ? null : $id_raw), 'affected' => \pg_affected_rows($result), ]; break; } } } } ?>