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": { "require": {
"envms/fluentpdo": "^1.1", "envms/fluentpdo": "^2.2",
"pear/console_table": "^1.3", "pear/console_table": "^1.3",
"brenard/php-unidecode": "dev-master", "brenard/php-unidecode": "dev-master",
"smarty/smarty": "3.1.34", "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", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"content-hash": "d528bc17185d97252de5ee65c0489059", "content-hash": "372e3ce1ce40fd466379b8709b0f7c5a",
"packages": [ "packages": [
{ {
"name": "brenard/php-unidecode", "name": "brenard/php-unidecode",
@ -103,23 +103,31 @@
}, },
{ {
"name": "envms/fluentpdo", "name": "envms/fluentpdo",
"version": "v1.1.3", "version": "v2.2.4",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/envms/fluentpdo.git", "url": "https://github.com/envms/fluentpdo.git",
"reference": "7d31e9b9028466ec41b0a0760b1491b091bcf8e8" "reference": "1985e0e8406a56140f387bc9bec786b419cbeccc"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/envms/fluentpdo/zipball/7d31e9b9028466ec41b0a0760b1491b091bcf8e8", "url": "https://api.github.com/repos/envms/fluentpdo/zipball/1985e0e8406a56140f387bc9bec786b419cbeccc",
"reference": "7d31e9b9028466ec41b0a0760b1491b091bcf8e8", "reference": "1985e0e8406a56140f387bc9bec786b419cbeccc",
"shasum": "" "shasum": ""
}, },
"require": {
"ext-pdo": "*",
"php": ">=7.1"
},
"require-dev": {
"envms/fluent-test": "^1.0",
"phpunit/phpunit": "^8.0"
},
"type": "library", "type": "library",
"autoload": { "autoload": {
"files": [ "psr-4": {
"FluentPDO/FluentPDO.php" "Envms\\FluentPDO\\": "src/"
] }
}, },
"notification-url": "https://packagist.org/downloads/", "notification-url": "https://packagist.org/downloads/",
"license": [ "license": [
@ -129,7 +137,7 @@
"authors": [ "authors": [
{ {
"name": "envms", "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.", "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": { "support": {
"issues": "https://github.com/envms/fluentpdo/issues", "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", "name": "geekwright/po",
@ -2850,5 +2858,5 @@
"prefer-lowest": false, "prefer-lowest": false,
"platform": [], "platform": [],
"platform-dev": [], "platform-dev": [],
"plugin-api-version": "2.0.0" "plugin-api-version": "2.3.0"
} }

View file

@ -1,102 +1,27 @@
<?php <?php
use EesyPHP\Db;
use EesyPHP\Hook; use EesyPHP\Hook;
use EesyPHP\Log; use EesyPHP\Log;
use Unidecode\Unidecode; use Unidecode\Unidecode;
if (!isset($db_dsn)) { $db = new Db(
Log :: fatal('Database DSN not configured'); isset($db_dsn)?$db_dsn:null,
exit(1);
}
try {
$pdo = new PDO(
$db_dsn,
isset($db_user)?$db_user:null, isset($db_user)?$db_user:null,
isset($db_pwd)?$db_pwd:null, isset($db_pwd)?$db_pwd:null,
isset($db_options)?$db_options:null isset($db_options)?$db_options:null,
); isset($db_date_format)?$db_date_format:null,
$pdo -> setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); isset($db_datetime_format)?$db_datetime_format:null
$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;
}
/* /*
* Methods to handle items * Methods to handle items
*/ */
function get_items($orderby='id', $raw_values=false) { function get_items($orderby='id', $raw_values=false) {
global $fpdo; global $db;
try { try {
$query = $fpdo -> from('item') $query = $db -> fpdo -> from('item')
-> orderBy($orderby); -> orderBy($orderby);
$result = $query -> execute(); $result = $query -> execute();
@ -109,7 +34,7 @@ function get_items($orderby='id', $raw_values=false) {
$items = array(); $items = array();
foreach ($info as $item) 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; return $items;
} }
} }
@ -120,9 +45,9 @@ function get_items($orderby='id', $raw_values=false) {
} }
function get_item($id, $raw_values=false) { function get_item($id, $raw_values=false) {
global $fpdo; global $db;
try { try {
$query = $fpdo -> from('item') $query = $db -> fpdo -> from('item')
-> where('id', $id); -> where('id', $id);
$result = $query -> execute(); $result = $query -> execute();
@ -133,7 +58,7 @@ function get_item($id, $raw_values=false) {
if ($raw_values) if ($raw_values)
return $info; return $info;
return _format_row_info($info, array('date')); return $db -> format_row_info($info, array('date'));
} }
} }
catch (Exception $e) { catch (Exception $e) {
@ -143,10 +68,10 @@ function get_item($id, $raw_values=false) {
} }
function add_item($values) { function add_item($values) {
global $fpdo; global $db;
$values['date'] = db_time2datetime(time()); $values['date'] = $db -> time2datetime(time());
try { try {
$result = $fpdo -> insertInto('item') $result = $db -> fpdo -> insertInto('item')
-> values($values) -> values($values)
-> execute(); -> execute();
@ -164,7 +89,7 @@ function add_item($values) {
} }
function update_item($id, $changes) { function update_item($id, $changes) {
global $fpdo; global $db;
if (!is_array($changes)) if (!is_array($changes))
return false; return false;
@ -174,10 +99,10 @@ function update_item($id, $changes) {
if (!is_array($item)) return false; if (!is_array($item)) return false;
if (isset($changes['date']) && !is_null($changes['date'])) if (isset($changes['date']) && !is_null($changes['date']))
$changes['date'] = db_time2datetime($changes['date']); $changes['date'] = $db -> time2datetime($changes['date']);
try { try {
$result = $fpdo -> update('item') $result = $db -> fpdo -> update('item')
-> set($changes) -> set($changes)
-> where('id', $id) -> where('id', $id)
-> execute(); -> execute();
@ -207,9 +132,9 @@ function archive_item($id) {
} }
function delete_item($id) { function delete_item($id) {
global $fpdo; global $db;
try { try {
$result = $fpdo -> deleteFrom('item') $result = $db -> fpdo -> deleteFrom('item')
-> where('id', $id) -> where('id', $id)
-> execute(); -> execute();
@ -225,7 +150,7 @@ function delete_item($id) {
} }
function search_items($params) { function search_items($params) {
global $fpdo, $db_dsn; global $db, $db_dsn;
// Detect PgSQL backend // Detect PgSQL backend
$is_pgsql = (strpos($db_dsn, "pgsql:") === 0); $is_pgsql = (strpos($db_dsn, "pgsql:") === 0);
@ -294,7 +219,7 @@ function search_items($params) {
} }
try { try {
$query = $fpdo -> from('item'); $query = $db -> fpdo -> from('item');
if (!empty($where)) if (!empty($where))
$query -> where($where); $query -> where($where);
foreach ($patterns_where as $patterns_word) foreach ($patterns_where as $patterns_word)
@ -318,7 +243,7 @@ function search_items($params) {
$rows = $result -> fetchAll(); $rows = $result -> fetchAll();
$items = array(); $items = array();
foreach ($rows as $row) { foreach ($rows as $row) {
$items[] = _format_row_info($row, array('date')); $items[] = $db -> format_row_info($row, array('date'));
} }
if (isset($params['all'])) { if (isset($params['all'])) {
return array( return array(
@ -330,7 +255,7 @@ function search_items($params) {
'items' => $items 'items' => $items
); );
} }
$query_count = $fpdo -> from('item') $query_count = $db -> fpdo -> from('item')
-> select(null) -> select(null)
-> select('count(*) as count'); -> select('count(*) as count');
if (!empty($where)) if (!empty($where))
@ -400,10 +325,10 @@ function export_items($fd=null) {
} }
function restore_items($fd=null) { function restore_items($fd=null) {
global $fpdo; global $db;
if (!$fd) $fd = fopen('php://stdin', 'r'); if (!$fd) $fd = fopen('php://stdin', 'r');
try { try {
$result = $fpdo -> deleteFrom('item') $result = $db -> fpdo -> deleteFrom('item')
-> execute(); -> execute();
if ($result === false) { if ($result === false) {
Log :: error("An unknown error occured truncating item table in database."); Log :: error("An unknown error occured truncating item table in database.");
@ -442,10 +367,10 @@ function restore_items($fd=null) {
array_key_exists($first_row[$i], $mapping)? array_key_exists($first_row[$i], $mapping)?
$mapping[$first_row[$i]]: $mapping[$first_row[$i]]:
$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; $values[$field] = $value;
} }
$result = $fpdo -> insertInto('item') $result = $db -> fpdo -> insertInto('item')
-> values($values) -> values($values)
-> execute(); -> execute();

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;
}
}