Compare commits
10 Commits
e2f6cb2246
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
777b531ce7 | ||
|
|
9a83c3b52e | ||
|
|
86b781857f | ||
|
|
a07065ab8c | ||
|
|
27e80613c7 | ||
|
|
e65701fa56 | ||
|
|
2a6e034f01 | ||
|
|
881693402a | ||
|
|
a2a07ceccf | ||
|
|
559558a530 |
4
.env.example
Normal file
4
.env.example
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
# Database configuration
|
||||||
|
DB_DSN=odbc:Driver=FreeTDS; Server=localhost; Port=1218; Database=mydb
|
||||||
|
DB_USER=myuser
|
||||||
|
DB_PASSWORD=changeme
|
||||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1,2 +1,3 @@
|
|||||||
vendor
|
vendor
|
||||||
*.lock
|
*.lock
|
||||||
|
.env
|
||||||
|
|||||||
24
config/configuration.local.php
Normal file
24
config/configuration.local.php
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Database configuration - credentials loaded from environment variables
|
||||||
|
*/
|
||||||
|
|
||||||
|
$getEnvOrThrow = function(string $name): string {
|
||||||
|
$value = getenv($name);
|
||||||
|
if ($value === false || $value === '') {
|
||||||
|
throw new \RuntimeException("Environment variable {$name} is not set");
|
||||||
|
}
|
||||||
|
return $value;
|
||||||
|
};
|
||||||
|
|
||||||
|
return array('db_req' =>
|
||||||
|
array(
|
||||||
|
'driver_class' => '\PDO',
|
||||||
|
'dsn' => $getEnvOrThrow('DB_DSN'),
|
||||||
|
'driver_params' => array(
|
||||||
|
'username' => $getEnvOrThrow('DB_USER'),
|
||||||
|
'password' => $getEnvOrThrow('DB_PASSWORD'),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
);
|
||||||
@@ -23,26 +23,27 @@ class Connection
|
|||||||
* @return OdbcResultSet|resource|string
|
* @return OdbcResultSet|resource|string
|
||||||
* @throws SqlException
|
* @throws SqlException
|
||||||
*/
|
*/
|
||||||
public static function execute($sql, $values = array(), $fetchMode = \PDO::FETCH_ASSOC)
|
public static function execute($sql, $values = array(), $fetchMode = \PDO::FETCH_ASSOC, $hasOutput = null)
|
||||||
{
|
{
|
||||||
$statement = PDOWithFilters::prepare($sql);
|
$statement = PDOWithFilters::prepare($sql);
|
||||||
$success = $statement->execute(!empty($values) ? $values : null);
|
$success = $statement->execute(!empty($values) ? $values : null);
|
||||||
|
|
||||||
if (!$success) {
|
if (!$success) {
|
||||||
$statement->closeCursor();
|
|
||||||
throw new SqlException('SQL There was an error executing the request');
|
throw new SqlException('SQL There was an error executing the request');
|
||||||
}
|
}
|
||||||
|
|
||||||
$rows = $statement->fetchAll($fetchMode);
|
$selectPos = strpos($sql, "SELECT");
|
||||||
|
if ((($selectPos !== false && $selectPos < 6) || strpos($sql, "OUTPUT INSERTED") !== false) && (($hasOutput !== null && $hasOutput !== false) || $hasOutput === null)) {
|
||||||
if (!is_array($rows)) {
|
$rows = $statement->fetchAll($fetchMode);
|
||||||
$statement->closeCursor();
|
if (!is_array($rows)) {
|
||||||
throw new SqlException('PDO Unable to retrieve the result');
|
throw new SqlException('PDO Unable to retrieve the result');
|
||||||
|
}
|
||||||
|
return new OdbcResultSet($rows);
|
||||||
}
|
}
|
||||||
|
|
||||||
$statement->closeCursor();
|
$statement->closeCursor();
|
||||||
|
|
||||||
return new OdbcResultSet($rows);
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -25,10 +25,10 @@ class DbHelper
|
|||||||
ORDER BY text;";
|
ORDER BY text;";
|
||||||
|
|
||||||
|
|
||||||
$results = Connection::execute($sql);
|
$results = Connection::execute($sql)->to_array();
|
||||||
|
|
||||||
if($withJeunesse) {
|
if($withJeunesse) {
|
||||||
array_unshift($results->to_array(), array('code' => 'J', 'text' => 'Jeunesse'));
|
array_unshift($results, array('code' => 'J', 'text' => 'Jeunesse'));
|
||||||
}
|
}
|
||||||
|
|
||||||
return $results;
|
return $results;
|
||||||
|
|||||||
101
src/Db/OdbcResultSet.php
Normal file
101
src/Db/OdbcResultSet.php
Normal file
@@ -0,0 +1,101 @@
|
|||||||
|
<?php
|
||||||
|
namespace Bsr\Db;
|
||||||
|
|
||||||
|
class OdbcResultSet implements \Iterator, \ArrayAccess, \Countable
|
||||||
|
{
|
||||||
|
public $length;
|
||||||
|
|
||||||
|
private $results;
|
||||||
|
private $error = false;
|
||||||
|
private $num_fields;
|
||||||
|
private $num_rows;
|
||||||
|
private $cursor_index;
|
||||||
|
|
||||||
|
public function __construct($resultset)
|
||||||
|
{
|
||||||
|
$this->results = $resultset;
|
||||||
|
$this->num_fields = is_array(current($resultset)) ? count(current($resultset)) : count($resultset);
|
||||||
|
$this->num_rows = count($this->results);
|
||||||
|
$this->length = $this->num_rows;
|
||||||
|
$this->cursor_index = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get_num_rows()
|
||||||
|
{
|
||||||
|
return $this->num_rows;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function is_error()
|
||||||
|
{
|
||||||
|
return ($this->error ? true : false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get_error()
|
||||||
|
{
|
||||||
|
return $this->error;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get_row()
|
||||||
|
{
|
||||||
|
return $this->current();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function to_array()
|
||||||
|
{
|
||||||
|
return $this->results;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Implementing Countable
|
||||||
|
public function count(): int {
|
||||||
|
return $this->get_num_rows();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Implementing ArrayAccess
|
||||||
|
public function offsetExists(mixed $offset): bool
|
||||||
|
{
|
||||||
|
return !$this->error && $offset < $this->length && $offset >= 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function offsetGet(mixed $offset): mixed
|
||||||
|
{
|
||||||
|
return $this->offsetExists($offset) ? $this->results[$offset] : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function offsetSet(mixed $offset, mixed $value): void
|
||||||
|
{
|
||||||
|
if($this->offsetExists($offset)) {
|
||||||
|
$this->results[$offset] = $value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function offsetUnset(mixed $offset): void
|
||||||
|
{
|
||||||
|
throw new \RuntimeException("Unsetting elements is not supported.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Implementing Iterator
|
||||||
|
public function current(): mixed
|
||||||
|
{
|
||||||
|
return $this->offsetGet($this->cursor_index);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function key(): mixed
|
||||||
|
{
|
||||||
|
return $this->cursor_index;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function next(): void
|
||||||
|
{
|
||||||
|
++$this->cursor_index;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function rewind(): void
|
||||||
|
{
|
||||||
|
$this->cursor_index = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function valid(): bool
|
||||||
|
{
|
||||||
|
return $this->offsetExists($this->cursor_index);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user