Возможно ли иметь преобразователь DateTime для каждой основной РСУБД?

Я пытаюсь разработать свой собственный ORM Framework поверх PDO это следует концепции Active Record и прост в использовании. Окунувшись в нее, я понял, что у каждой реляционной базы данных есть свое понимание типов данных даты и времени. Я хотел бы использовать в моем ORM только PHP DateTime и сопоставьте его с лежащей в основе СУБД, чтобы мы могли использовать преимущества этих типов данных. Но я не уверен, если это возможно, просто подумайте о сравнении периода и так далее. На самом деле, это также, где DBAL Доктрины, кажется, не заботится. Они просто говорят not supported на разных типах данных для даты и времени, когда дело доходит до различий.

Я хочу что-то вроде этого:

MySQL:      PHP DateTime => maps to MySQL DateTime field
PostgreSQL: PHP DateTime => maps to a splitted date field and a time field
Oracle:     PHP DateTime => maps to TIMESTAMP
...

Пользователь должен иметь возможность установить свое поле DateTime с помощью метода установки для этого реляционного объекта. Когда выполняются операции выбора, вставки, обновления или удаления, они должны быть сопоставлены с этим лежащим в основе, возможно, разделенным полем даты и времени. То же самое должно появиться, если пользователь запрашивает это значение через метод getter.

Скажите, пожалуйста, как это возможно, и приведите несколько примеров. Большое спасибо! 🙂

Изменить: я немного поиграл с адаптером, как указано ниже. Я думаю, что это решает проблему:

<?php
namespace Diana\Core\Persistence\Sql\Dbal\Gateway;

interface IAdapter
{
/**
* Drills an DateTime instance down to underlaying RDBMS date and time string.
*
* @param \DateTime $date
* @return string
*/
public function drillDownDateTime(\DateTime $date);/**
* Parse the RDBMS rows back to an DateTime instance.
*
* @param array $rows
* @return \DateTime
*/
public function parseDateTime(array $rows);
}<?php
namespace Diana\Core\Persistence\Sql\Dbal\Gateway;

class OracleAdapter implements IAdapter
{
const FORMAT = 'Y-m-d H:i:s e';
/**
* @inheritdoc
*/
public function drillDownDateTime(\DateTime $date)
{
return $date->format(self::FORMAT);
}

/**
* @inheritdoc
*/
public function parseDateTime(array $rows)
{
return \DateTime::createFromFormat(self::FORMAT, $rows[0]);
}
}

<?php
namespace Diana\Core\Persistence\Sql\Dbal\Gateway;

class PostgreSqlAdapter implements IAdapter
{
const FORMAT = 'Y-m-d H:i:s e';

/**
* @inheritdoc
*/
public function drillDownDateTime(\DateTime $date)
{
return $date->format(self::FORMAT);
}

/**
* @inheritdoc
*/
public function parseDateTime(array $rows)
{
return \DateTime::createFromFormat(self::FORMAT, $rows[0]);
}
}

Как я нашел в документации в

оракул

MySQL

PostgreSQL

Это должно работать. В MySQL часовой пояс является параметром в базе данных, поэтому мы не можем позаботиться о нем. Это также просто пример. Но эти файлы в готовой версии скоро станут частью моего фреймворк. Из-за моего собственного класса Date, который автоматически выводит локальную строку даты при выводе, мы используем DateTime в качестве параметра здесь, так что оба могут быть переданы.

2

Решение

Создайте интерфейс адаптера!

<?php

interface DbAdapterInterface
{
/**
* @param DateTime $date
* @return string
*/
public function convertFromDateTime(DateTime $date);

/**
* @param DateTime $date
* @return array
*/
public function convertToDateTime(array $row);
}

class MySqlAdapter implements DbAdapterInterface
{
public function convertFromDateTime(DateTime $date)
{
return $date->format('Y-m-d H:i:s');
}

public function convertToDateTime(array $row)
{
return new DateTime($row['date']);
}
}

class OracleAdapter implements DbAdapterInterface
{
public function convertFromDateTime(DateTime $date)
{
return $date->getTimestamp();
}

public function convertToDateTime(array $row)
{
return new DateTime('@'.$row['date']);
}
}

class Db
{
/** @var DbAdapterInterface $adapter */
private $adapter;

public function setAdapter(DbAdapterInterface $adapter)
{
$this->adapter = $adapter;
}

public function insert($data)
{
$date = $data['date'];
$dateString = $this->adapter->convertFromDateTime($date);
// do your insert
return $dateString;
}

public function findById($id)
{
// fetch row by id here, this is just an example, I'm using the id as the date string
$row = ['date' => $id];
$row = $this->adapter->convertToDateTime($row);
// do your insert
return $row;
}
}// Example

$data = [
'date' => new DateTime(),
];

$db = new Db();
$db->setAdapter(new MySqlAdapter());
echo $db->insert($data)."\n";
$db->setAdapter(new OracleAdapter());
echo $db->insert($data)."\n";

$time = '1493308146';
var_dump( $db->findById($time));

$db->setAdapter(new MySqlAdapter());
$time = '2014-09-18 22:00:00';
var_dump( $db->findById($time));

Смотрите здесь для рабочего примера: https://3v4l.org/pYgbE

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]