-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
3 changed files
with
227 additions
and
227 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,61 +1,61 @@ | ||
# Doctrine DBAL for Microsoft Access | ||
An implementation of the [doctrine/dbal](https://github.com/doctrine/dbal) library to support **Microsoft Access databases** in **Microsoft OS**. | ||
|
||
There are some functionalities that are not supported by Microsoft Access in a PDO-based connection. For these functionalities the implementation uses a direct connection through ODBC. | ||
|
||
## OS Requirements | ||
- Microsoft Access Database Engine Redistributable ([2010](https://www.microsoft.com/download/details.aspx?id=13255) or [2016](https://www.microsoft.com/download/details.aspx?id=54920)). | ||
- Register a **DSN** in **ODBC Data Source Administrator** (odbcad32.exe). | ||
|
||
## Installation | ||
|
||
1) Install via [composer](https://getcomposer.org/) | ||
|
||
```shell script | ||
composer require zoilomora/doctrine-dbal-msaccess | ||
``` | ||
|
||
### Register a **DSN** | ||
We don't need to reinvent the wheel, on the internet there are hundreds of tutorials on how to set up a DSN for Microsoft Access. | ||
I leave you a [video](https://www.youtube.com/watch?v=biSjA8ms_Wk) that I think explains it perfectly. | ||
Once the DSN is configured we will have to configure the connection in the following way: | ||
```php | ||
$connection = \Doctrine\DBAL\DriverManager::getConnection( | ||
[ | ||
'driverClass' => \ZoiloMora\Doctrine\DBAL\Driver\MicrosoftAccess\Driver::class, | ||
'dsn' => 'name of the created dsn', | ||
] | ||
); | ||
``` | ||
## Discovered problems | ||
### Character encoding problems | ||
The default character encoding in Access databases is [Windows-1252](https://en.wikipedia.org/wiki/Windows-1252). | ||
If you want to convert the data to UTF-8, a simple solution would be: | ||
```php | ||
$field = \mb_convert_encoding($field, 'UTF-8', 'Windows-1252'); | ||
``` | ||
If you want all the data to be encoded automatically to UTF-8 (with the performance reduction that it may imply) | ||
configure the driver as follows: | ||
```php | ||
$connection = \Doctrine\DBAL\DriverManager::getConnection( | ||
[ | ||
'driverClass' => \ZoiloMora\Doctrine\DBAL\Driver\MicrosoftAccess\Driver::class, | ||
'dsn' => 'name of the created dsn', | ||
'driverOptions' => [ | ||
'charset' => 'UTF-8', | ||
], | ||
] | ||
); | ||
``` | ||
## License | ||
Licensed under the [MIT license](http://opensource.org/licenses/MIT) | ||
Read [LICENSE](LICENSE) for more information | ||
# Doctrine DBAL for Microsoft Access | ||
An implementation of the [doctrine/dbal](https://github.com/doctrine/dbal) library to support **Microsoft Access databases** in **Microsoft OS**. | ||
|
||
There are some functionalities that are not supported by Microsoft Access in a PDO-based connection. For these functionalities the implementation uses a direct connection through ODBC. | ||
|
||
## OS Requirements | ||
- Microsoft Access Database Engine Redistributable ([2010](https://www.microsoft.com/download/details.aspx?id=13255) or [2016](https://www.microsoft.com/download/details.aspx?id=54920)). | ||
- Register a **DSN** in **ODBC Data Source Administrator** (odbcad32.exe). | ||
|
||
## Installation | ||
|
||
1) Install via [composer](https://getcomposer.org/) | ||
|
||
```shell script | ||
composer require zoilomora/doctrine-dbal-msaccess | ||
``` | ||
|
||
### Register a **DSN** | ||
We don't need to reinvent the wheel, on the internet there are hundreds of tutorials on how to set up a DSN for Microsoft Access. | ||
I leave you a [video](https://www.youtube.com/watch?v=biSjA8ms_Wk) that I think explains it perfectly. | ||
Once the DSN is configured we will have to configure the connection in the following way: | ||
```php | ||
$connection = \Doctrine\DBAL\DriverManager::getConnection( | ||
[ | ||
'driverClass' => \ZoiloMora\Doctrine\DBAL\Driver\MicrosoftAccess\Driver::class, | ||
'dsn' => 'name of the created dsn', | ||
] | ||
); | ||
``` | ||
## Discovered problems | ||
### Character encoding problems | ||
The default character encoding in Access databases is [Windows-1252](https://en.wikipedia.org/wiki/Windows-1252). | ||
If you want to convert the data to UTF-8, a simple solution would be: | ||
```php | ||
$field = \mb_convert_encoding($field, 'UTF-8', 'Windows-1252'); | ||
``` | ||
If you want all the data to be encoded automatically to UTF-8 (with the performance reduction that it may imply) | ||
configure the driver as follows: | ||
```php | ||
$connection = \Doctrine\DBAL\DriverManager::getConnection( | ||
[ | ||
'driverClass' => \ZoiloMora\Doctrine\DBAL\Driver\MicrosoftAccess\Driver::class, | ||
'dsn' => 'name of the created dsn', | ||
'driverOptions' => [ | ||
'charset' => 'UTF-8', | ||
], | ||
] | ||
); | ||
``` | ||
## License | ||
Licensed under the [MIT license](http://opensource.org/licenses/MIT) | ||
Read [LICENSE](LICENSE) for more information |
240 changes: 120 additions & 120 deletions
240
src/Doctrine/DBAL/Driver/MicrosoftAccess/Statement.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,120 +1,120 @@ | ||
<?php | ||
declare(strict_types=1); | ||
|
||
namespace ZoiloMora\Doctrine\DBAL\Driver\MicrosoftAccess; | ||
|
||
use Doctrine\DBAL\ParameterType; | ||
|
||
final class Statement extends \Doctrine\DBAL\Driver\PDO\Statement | ||
{ | ||
private const FROM_ENCODING = 'Windows-1252'; | ||
|
||
private ?string $charset; | ||
|
||
protected function __construct(?string $charset = null) | ||
{ | ||
$this->charset = $charset; | ||
} | ||
|
||
public function bindParam($param, &$variable, $type = ParameterType::STRING, $length = null, $driverOptions = null) | ||
{ | ||
switch ($type) { | ||
case ParameterType::LARGE_OBJECT: | ||
case ParameterType::BINARY: | ||
if ($driverOptions === null) { | ||
$driverOptions = \PDO::SQLSRV_ENCODING_BINARY; | ||
} | ||
|
||
break; | ||
|
||
case ParameterType::ASCII: | ||
$type = ParameterType::STRING; | ||
$length = 0; | ||
$driverOptions = \PDO::SQLSRV_ENCODING_SYSTEM; | ||
break; | ||
} | ||
|
||
return parent::bindParam($param, $variable, $type, $length, $driverOptions); | ||
} | ||
|
||
public function bindValue($param, $value, $type = ParameterType::STRING) | ||
{ | ||
return $this->bindParam($param, $value, $type); | ||
} | ||
|
||
public function fetchOne() | ||
{ | ||
return $this->convertStringEncoding( | ||
parent::fetchOne() | ||
); | ||
} | ||
|
||
public function fetchNumeric() | ||
{ | ||
return $this->convertArrayEncoding( | ||
parent::fetchNumeric() | ||
); | ||
} | ||
|
||
public function fetchAssociative() | ||
{ | ||
return $this->convertArrayEncoding( | ||
parent::fetchAssociative() | ||
); | ||
} | ||
|
||
public function fetchAllNumeric(): array | ||
{ | ||
return $this->convertCollectionEncoding( | ||
parent::fetchAllNumeric() | ||
); | ||
} | ||
|
||
public function fetchFirstColumn(): array | ||
{ | ||
return $this->convertArrayEncoding( | ||
parent::fetchFirstColumn() | ||
); | ||
} | ||
|
||
public function fetchAllAssociative(): array | ||
{ | ||
return $this->convertCollectionEncoding( | ||
parent::fetchAllAssociative() | ||
); | ||
} | ||
|
||
private function convertCollectionEncoding(array $items): array | ||
{ | ||
\array_walk( | ||
$items, | ||
function (&$item) { | ||
$item = $this->convertArrayEncoding($item); | ||
} | ||
); | ||
|
||
return $items; | ||
} | ||
|
||
private function convertArrayEncoding(array $items): array | ||
{ | ||
foreach ($items as $key => $value) { | ||
$items[$key] = $this->convertStringEncoding($items[$key]); | ||
} | ||
|
||
return $items; | ||
} | ||
|
||
private function convertStringEncoding(?string $value): ?string | ||
{ | ||
if (null === $this->charset) { | ||
return $value; | ||
} | ||
|
||
if (null === $value) { | ||
return null; | ||
} | ||
|
||
return \mb_convert_encoding($value, $this->charset, self::FROM_ENCODING); | ||
} | ||
} | ||
<?php | ||
declare(strict_types=1); | ||
|
||
namespace ZoiloMora\Doctrine\DBAL\Driver\MicrosoftAccess; | ||
|
||
use Doctrine\DBAL\ParameterType; | ||
|
||
final class Statement extends \Doctrine\DBAL\Driver\PDO\Statement | ||
{ | ||
private const FROM_ENCODING = 'Windows-1252'; | ||
|
||
private ?string $charset; | ||
|
||
protected function __construct(?string $charset = null) | ||
{ | ||
$this->charset = $charset; | ||
} | ||
|
||
public function bindParam($param, &$variable, $type = ParameterType::STRING, $length = null, $driverOptions = null) | ||
{ | ||
switch ($type) { | ||
case ParameterType::LARGE_OBJECT: | ||
case ParameterType::BINARY: | ||
if ($driverOptions === null) { | ||
$driverOptions = \PDO::SQLSRV_ENCODING_BINARY; | ||
} | ||
|
||
break; | ||
|
||
case ParameterType::ASCII: | ||
$type = ParameterType::STRING; | ||
$length = 0; | ||
$driverOptions = \PDO::SQLSRV_ENCODING_SYSTEM; | ||
break; | ||
} | ||
|
||
return parent::bindParam($param, $variable, $type, $length, $driverOptions); | ||
} | ||
|
||
public function bindValue($param, $value, $type = ParameterType::STRING) | ||
{ | ||
return $this->bindParam($param, $value, $type); | ||
} | ||
|
||
public function fetchOne() | ||
{ | ||
return $this->convertStringEncoding( | ||
parent::fetchOne() | ||
); | ||
} | ||
|
||
public function fetchNumeric() | ||
{ | ||
return $this->convertArrayEncoding( | ||
parent::fetchNumeric() | ||
); | ||
} | ||
|
||
public function fetchAssociative() | ||
{ | ||
return $this->convertArrayEncoding( | ||
parent::fetchAssociative() | ||
); | ||
} | ||
|
||
public function fetchAllNumeric(): array | ||
{ | ||
return $this->convertCollectionEncoding( | ||
parent::fetchAllNumeric() | ||
); | ||
} | ||
|
||
public function fetchFirstColumn(): array | ||
{ | ||
return $this->convertArrayEncoding( | ||
parent::fetchFirstColumn() | ||
); | ||
} | ||
|
||
public function fetchAllAssociative(): array | ||
{ | ||
return $this->convertCollectionEncoding( | ||
parent::fetchAllAssociative() | ||
); | ||
} | ||
|
||
private function convertCollectionEncoding(array $items): array | ||
{ | ||
\array_walk( | ||
$items, | ||
function (&$item) { | ||
$item = $this->convertArrayEncoding($item); | ||
} | ||
); | ||
|
||
return $items; | ||
} | ||
|
||
private function convertArrayEncoding(array $items): array | ||
{ | ||
foreach ($items as $key => $value) { | ||
$items[$key] = $this->convertStringEncoding($items[$key]); | ||
} | ||
|
||
return $items; | ||
} | ||
|
||
private function convertStringEncoding(?string $value): ?string | ||
{ | ||
if (null === $this->charset) { | ||
return $value; | ||
} | ||
|
||
if (null === $value) { | ||
return null; | ||
} | ||
|
||
return \mb_convert_encoding($value, $this->charset, self::FROM_ENCODING); | ||
} | ||
} |
Oops, something went wrong.