Move DB stuff in EesyPHP namespace

This commit is contained in:
Benjamin Renard 2023-01-30 11:23:35 +01:00
parent c8659ea46f
commit 541b447cbf
Signed by: bn8
GPG key ID: 3E2E1CE1907115BC
4 changed files with 231 additions and 133 deletions

View file

@ -16,7 +16,7 @@
]
},
"require": {
"envms/fluentpdo": "^1.1",
"envms/fluentpdo": "^2.2",
"pear/console_table": "^1.3",
"brenard/php-unidecode": "dev-master",
"smarty/smarty": "3.1.34",

32
composer.lock generated
View file

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "d528bc17185d97252de5ee65c0489059",
"content-hash": "372e3ce1ce40fd466379b8709b0f7c5a",
"packages": [
{
"name": "brenard/php-unidecode",
@ -103,23 +103,31 @@
},
{
"name": "envms/fluentpdo",
"version": "v1.1.3",
"version": "v2.2.4",
"source": {
"type": "git",
"url": "https://github.com/envms/fluentpdo.git",
"reference": "7d31e9b9028466ec41b0a0760b1491b091bcf8e8"
"reference": "1985e0e8406a56140f387bc9bec786b419cbeccc"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/envms/fluentpdo/zipball/7d31e9b9028466ec41b0a0760b1491b091bcf8e8",
"reference": "7d31e9b9028466ec41b0a0760b1491b091bcf8e8",
"url": "https://api.github.com/repos/envms/fluentpdo/zipball/1985e0e8406a56140f387bc9bec786b419cbeccc",
"reference": "1985e0e8406a56140f387bc9bec786b419cbeccc",
"shasum": ""
},
"require": {
"ext-pdo": "*",
"php": ">=7.1"
},
"require-dev": {
"envms/fluent-test": "^1.0",
"phpunit/phpunit": "^8.0"
},
"type": "library",
"autoload": {
"files": [
"FluentPDO/FluentPDO.php"
]
"psr-4": {
"Envms\\FluentPDO\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
@ -129,7 +137,7 @@
"authors": [
{
"name": "envms",
"homepage": "http://env.ms"
"homepage": "https://env.ms"
}
],
"description": "FluentPDO is a quick and light PHP library for rapid query building. It features a smart join builder, which automatically creates table joins.",
@ -147,9 +155,9 @@
],
"support": {
"issues": "https://github.com/envms/fluentpdo/issues",
"source": "https://github.com/envms/fluentpdo/tree/legacy"
"source": "https://github.com/envms/fluentpdo/tree/v2.2.4"
},
"time": "2018-04-27T19:01:30+00:00"
"time": "2022-01-27T21:49:44+00:00"
},
{
"name": "geekwright/po",
@ -2850,5 +2858,5 @@
"prefer-lowest": false,
"platform": [],
"platform-dev": [],
"plugin-api-version": "2.0.0"
"plugin-api-version": "2.3.0"
}

View file

@ -1,103 +1,28 @@
<?php
use EesyPHP\Db;
use EesyPHP\Hook;
use EesyPHP\Log;
use Unidecode\Unidecode;
if (!isset($db_dsn)) {
Log :: fatal('Database DSN not configured');
exit(1);
}
try {
$pdo = new PDO(
$db_dsn,
isset($db_user)?$db_user:null,
isset($db_pwd)?$db_pwd:null,
isset($db_options)?$db_options:null
);
$pdo -> setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$fpdo = new FluentPDO($pdo);
$fpdo -> debug = function ($q) {
$time = sprintf('%0.3f', $q->getTime() * 1000) . ' ms';
$rows = ($q->getResult()) ? $q->getResult()->rowCount() : 0;
$query = $q->getQuery();
$msg = "# DB query ($time; rows = $rows) : $query";
$parameters = $q->getParameters();
if ($parameters) {
if (is_array($parameters)) {
$msg .= "\n# Parameters: '" . implode("', '", $parameters) . "'";
}
else {
$msg .= "\n# Parameters: '" . vardump($parameters) . "'";
}
}
Log :: debug($msg);
};
}
catch(Exception $e) {
Log :: error("Fail to connect to DB (DSN : '$db_dsn') : ".$e->getMessage());
Log :: fatal(_('Unable to connect to the database.'));
}
/*
* Handle date/datetime format
*/
function db_date2time($date) {
global $db_date_format;
setlocale(LC_TIME, "fr_FR");
$pdate = strptime($date, $db_date_format);
return mktime(
$pdate['tm_hour'], $pdate['tm_min'], $pdate['tm_sec'],
$pdate['tm_mon'] + 1, $pdate['tm_mday'], $pdate['tm_year'] + 1900
);
}
function db_time2date($time) {
global $db_date_format;
setlocale(LC_TIME, "fr_FR");
return strftime($db_date_format, $time);
}
function db_datetime2time($date) {
global $db_datetime_format;
setlocale(LC_TIME, "fr_FR");
$pdate = strptime($date, $db_datetime_format);
return mktime(
$pdate['tm_hour'], $pdate['tm_min'], $pdate['tm_sec'],
$pdate['tm_mon'] + 1, $pdate['tm_mday'], $pdate['tm_year'] + 1900
);
}
function db_time2datetime($time) {
global $db_datetime_format;
setlocale(LC_TIME, "fr_FR");
return strftime($db_datetime_format, $time);
}
/*
* Helper to format row info from DB
*/
function _format_row_info($row, $datetime_fields) {
// Convert datetime fields
foreach($datetime_fields as $field)
if ($row[$field])
$row[$field] = db_datetime2time($row[$field]);
return $row;
}
$db = new Db(
isset($db_dsn)?$db_dsn:null,
isset($db_user)?$db_user:null,
isset($db_pwd)?$db_pwd:null,
isset($db_options)?$db_options:null,
isset($db_date_format)?$db_date_format:null,
isset($db_datetime_format)?$db_datetime_format:null
);
/*
* Methods to handle items
*/
function get_items($orderby='id', $raw_values=false) {
global $fpdo;
global $db;
try {
$query = $fpdo -> from('item')
-> orderBy($orderby);
$query = $db -> fpdo -> from('item')
-> orderBy($orderby);
$result = $query -> execute();
if ($result !== false) {
@ -109,7 +34,7 @@ function get_items($orderby='id', $raw_values=false) {
$items = array();
foreach ($info as $item)
$items[$item['id']] = _format_row_info($item, array('date'));
$items[$item['id']] = $db -> format_row_info($item, array('date'));
return $items;
}
}
@ -120,10 +45,10 @@ function get_items($orderby='id', $raw_values=false) {
}
function get_item($id, $raw_values=false) {
global $fpdo;
global $db;
try {
$query = $fpdo -> from('item')
-> where('id', $id);
$query = $db -> fpdo -> from('item')
-> where('id', $id);
$result = $query -> execute();
if ($result !== false) {
@ -133,7 +58,7 @@ function get_item($id, $raw_values=false) {
if ($raw_values)
return $info;
return _format_row_info($info, array('date'));
return $db -> format_row_info($info, array('date'));
}
}
catch (Exception $e) {
@ -143,12 +68,12 @@ function get_item($id, $raw_values=false) {
}
function add_item($values) {
global $fpdo;
$values['date'] = db_time2datetime(time());
global $db;
$values['date'] = $db -> time2datetime(time());
try {
$result = $fpdo -> insertInto('item')
-> values($values)
-> execute();
$result = $db -> fpdo -> insertInto('item')
-> values($values)
-> execute();
if ($result !== false) {
$item = get_item($result);
@ -164,7 +89,7 @@ function add_item($values) {
}
function update_item($id, $changes) {
global $fpdo;
global $db;
if (!is_array($changes))
return false;
@ -174,13 +99,13 @@ function update_item($id, $changes) {
if (!is_array($item)) return false;
if (isset($changes['date']) && !is_null($changes['date']))
$changes['date'] = db_time2datetime($changes['date']);
$changes['date'] = $db -> time2datetime($changes['date']);
try {
$result = $fpdo -> update('item')
-> set($changes)
-> where('id', $id)
-> execute();
$result = $db -> fpdo -> update('item')
-> set($changes)
-> where('id', $id)
-> execute();
if ($result !== false) {
Log :: info("Item #$id updated");
@ -207,11 +132,11 @@ function archive_item($id) {
}
function delete_item($id) {
global $fpdo;
global $db;
try {
$result = $fpdo -> deleteFrom('item')
-> where('id', $id)
-> execute();
$result = $db -> fpdo -> deleteFrom('item')
-> where('id', $id)
-> execute();
if ($result !== false) {
Log :: info("Item #$id deleted");
@ -225,7 +150,7 @@ function delete_item($id) {
}
function search_items($params) {
global $fpdo, $db_dsn;
global $db, $db_dsn;
// Detect PgSQL backend
$is_pgsql = (strpos($db_dsn, "pgsql:") === 0);
@ -294,7 +219,7 @@ function search_items($params) {
}
try {
$query = $fpdo -> from('item');
$query = $db -> fpdo -> from('item');
if (!empty($where))
$query -> where($where);
foreach ($patterns_where as $patterns_word)
@ -318,7 +243,7 @@ function search_items($params) {
$rows = $result -> fetchAll();
$items = array();
foreach ($rows as $row) {
$items[] = _format_row_info($row, array('date'));
$items[] = $db -> format_row_info($row, array('date'));
}
if (isset($params['all'])) {
return array(
@ -330,9 +255,9 @@ function search_items($params) {
'items' => $items
);
}
$query_count = $fpdo -> from('item')
-> select(null)
-> select('count(*) as count');
$query_count = $db -> fpdo -> from('item')
-> select(null)
-> select('count(*) as count');
if (!empty($where))
$query_count -> where($where);
foreach ($patterns_where as $patterns_word)
@ -400,11 +325,11 @@ function export_items($fd=null) {
}
function restore_items($fd=null) {
global $fpdo;
global $db;
if (!$fd) $fd = fopen('php://stdin', 'r');
try {
$result = $fpdo -> deleteFrom('item')
-> execute();
$result = $db -> fpdo -> deleteFrom('item')
-> execute();
if ($result === false) {
Log :: error("An unknown error occured truncating item table in database.");
return false;
@ -442,12 +367,12 @@ function restore_items($fd=null) {
array_key_exists($first_row[$i], $mapping)?
$mapping[$first_row[$i]]:
$first_row[$i]);
$value = (in_array($field, $datetime_fields)?db_time2datetime($row[$i]):$row[$i]);
$value = (in_array($field, $datetime_fields)?$db -> time2datetime($row[$i]):$row[$i]);
$values[$field] = $value;
}
$result = $fpdo -> insertInto('item')
-> values($values)
-> execute();
$result = $db -> fpdo -> insertInto('item')
-> values($values)
-> execute();
if ($result !== false) {
$restored++;

165
src/Db.php Normal file
View file

@ -0,0 +1,165 @@
<?php
namespace EesyPHP;
use EesyPHP\Log;
use function EesyPHP\vardump;
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 string $date_format = '%Y-%m-%d';
/**
* Datetime format as returned by database
* @var string
*/
protected string $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(_('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;
}
}