eesyphp/src/Db.php

163 lines
4.5 KiB
PHP

<?php
namespace EesyPHP;
use Exception;
use PDO;
use \Envms\FluentPDO\Query;
class Db {
/**
* The PDO object of the database connection
* @var PDO
*/
public $pdo;
/**
* The PDO object of the database connection
* @var \Envms\FluentPDO\Query
*/
public $fpdo;
/**
* Date format as returned by database
* @var string
*/
protected $date_format = '%Y-%m-%d';
/**
* Datetime format as returned by database
* @var string
*/
protected $datetime_format = '%Y-%m-%d %H:%M:%S';
/**
* Locale for time (as expected by LC_TIME)
* @var string|null
*/
protected $locale_time = null;
/**
* Connect to database and return FluentPDO Query object
* @param string $dsn Database DSN
* @param string|null $user Username (optional)
* @param string|null $password password (optional)
* @param string|array $options Connection options (optional)
* @param string|null $date_format Date format in DB (optional)
* @param string|null $datetime_format Datetime format in DB (optional)
* @param string|null $locale_time Locale for time (optional)
* @return void
*/
public function __construct($dsn, $user=null, $password=null, $options=null,
$date_format=null, $datetime_format=null, $locale_time=null) {
if (!$dsn) {
Log :: fatal('Database DSN not configured');
return;
}
if ($date_format) $this -> date_format = $date_format;
if ($datetime_format) $this -> datetime_format = $datetime_format;
if ($locale_time) $this -> locale_time = $locale_time;
try {
// Connect to database
$this -> pdo = new PDO($dsn, $user, $password, $options);
$this -> fpdo = new Query($this -> pdo);
// Register the debug query handler to log it
$this -> fpdo -> debug = array('\\EesyPHP\\Db', 'debug_query');
Log :: trace("DB connection established (DSN: '%s')", $dsn);
}
catch(Exception $e) {
Log :: error("Fail to connect to DB (DSN : '%s') : %s", $dsn, $e->getMessage());
Log :: fatal(I18n::_('Unable to connect to the database.'));
}
}
/**
* Debug a query
* @param \Envms\FluentPDO\Queries\Base $q
* @return void
*/
public static function debug_query($q) {
$msg = "# DB query";
if ($q->getResult())
$msg .= sprintf(
" (%0.3f ms; rows = %d)",
$q->getExecutionTime() * 1000,
$q->getResult()->rowCount()
);
$msg .= ": ".$q->getQuery();
$parameters = $q->getParameters();
if ($parameters) {
if (is_array($parameters)) {
$msg .= "\n# Parameters: '" . implode("', '", $parameters) . "'";
}
else { // @phpstan-ignore-line
$msg .= "\n# Parameters: '" . vardump($parameters) . "'";
}
}
Log :: debug('DEBUG', $msg);
}
/*
* Handle date/datetime format
*/
public function set_locale() {
if ($this -> locale_time)
setlocale(LC_TIME, $this -> locale_time);
}
public function date2time($date) {
$this -> set_locale();
$pdate = strptime($date, $this -> date_format);
return mktime(
$pdate['tm_hour'], $pdate['tm_min'], $pdate['tm_sec'],
$pdate['tm_mon'] + 1, $pdate['tm_mday'], $pdate['tm_year'] + 1900
);
}
public function time2date($time) {
$this -> set_locale();
return strftime($this -> date_format, $time);
}
public function datetime2time($date) {
$this -> set_locale();
$pdate = strptime($date, $this -> datetime_format);
return mktime(
$pdate['tm_hour'], $pdate['tm_min'], $pdate['tm_sec'],
$pdate['tm_mon'] + 1, $pdate['tm_mday'], $pdate['tm_year'] + 1900
);
}
public function time2datetime($time) {
$this -> set_locale();
return strftime($this -> datetime_format, $time);
}
/**
* Helper method to format row info
* @param array<string,mixed> $row The raw row info
* @param array<string> $datetime_fields List of field in datetime format
* @param array<string> $date_fields List of field in date format
* @return array
*/
public function format_row_info($row, $datetime_fields=null, $date_fields=null) {
// Convert datetime fields
if (is_array($datetime_fields))
foreach($datetime_fields as $field)
if ($row[$field])
$row[$field] = $this -> datetime2time($row[$field]);
// Convert date fields
if (is_array($date_fields))
foreach($date_fields as $field)
if ($row[$field])
$row[$field] = $this -> date2time($row[$field]);
return $row;
}
}