Add database connexion #6

Merged
maxime.batista merged 7 commits from setup-database into master 1 year ago

8
.gitignore vendored

@ -1,11 +1,13 @@
.idea .*
.vs
.code
vendor vendor
composer.lock composer.lock
*.phar *.phar
/dist /dist
# sqlite database files
*.sqlite
views-mappings.php views-mappings.php
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

@ -102,6 +102,7 @@ the file is replaced with `prod-config-file.php` by the CI when deploying to the
The two profiles declares an `_asset(string $uri)` function, used by the `/config.php::asset` method, but with different implementations : The two profiles declares an `_asset(string $uri)` function, used by the `/config.php::asset` method, but with different implementations :
### Development profile ### Development profile
```php ```php
$hostname = getHostName(); $hostname = getHostName();
$front_url = "http://$hostname:5173"; $front_url = "http://$hostname:5173";
@ -110,8 +111,6 @@ function _asset(string $assetURI): string {
global $front_url; global $front_url;
return $front_url . "/" . $assetURI; return $front_url . "/" . $assetURI;
} }
``` ```
The simplest profile, simply redirect all assets to the development server The simplest profile, simply redirect all assets to the development server

@ -32,7 +32,7 @@ steps:
- sed -iE 's/\\/\\*PROFILE_FILE\\*\\/\\s*".*"/"profiles\\/prod-config-profile.php"/' config.php - sed -iE 's/\\/\\*PROFILE_FILE\\*\\/\\s*".*"/"profiles\\/prod-config-profile.php"/' config.php
- composer install && composer update - composer install && composer update
- rm profiles/dev-config-profile.php - rm profiles/dev-config-profile.php
- mv src config.php profiles vendor /outputs/ - mv src config.php sql profiles vendor /outputs/
- image: eeacms/rsync:latest - image: eeacms/rsync:latest
name: Deliver on staging server branch name: Deliver on staging server branch
@ -49,4 +49,3 @@ steps:
- chmod 0600 ~/.ssh - chmod 0600 ~/.ssh
- chmod 0500 ~/.ssh/id_rsa* - chmod 0500 ~/.ssh/id_rsa*
- rsync -avz -e "ssh -p 80 -o 'StrictHostKeyChecking=no'" --delete /outputs/* iqball@maxou.dev:/server/nginx/IQBall/$DRONE_BRANCH - rsync -avz -e "ssh -p 80 -o 'StrictHostKeyChecking=no'" --delete /outputs/* iqball@maxou.dev:/server/nginx/IQBall/$DRONE_BRANCH

@ -6,6 +6,8 @@
}, },
"require": { "require": {
"altorouter/altorouter": "1.2.0", "altorouter/altorouter": "1.2.0",
"ext-json": "*" "ext-json": "*",
"ext-pdo": "*",
"ext-pdo_sqlite": "*"
} }
} }

@ -16,4 +16,8 @@ function asset(string $assetURI): string {
return _asset($assetURI); return _asset($assetURI);
} }
global $_data_source_name;
$data_source_name = $_data_source_name;
const DATABASE_USER = _DATABASE_USER;
const DATABASE_PASSWORD = _DATABASE_PASSWORD;

@ -11,6 +11,8 @@ export function renderView(Component: FunctionComponent, args: {}) {
document.getElementById('root') as HTMLElement document.getElementById('root') as HTMLElement
); );
console.log(args)
root.render( root.render(
<React.StrictMode> <React.StrictMode>
<Component {...args}/> <Component {...args}/>

@ -1,12 +1,19 @@
import ReactDOM from "react-dom/client";
import React from "react";
interface DisplayResultsProps {
results: readonly { name: string, description: string}[]
}
export default function DisplayResults({password, username}: any) { export default function DisplayResults({results}: DisplayResultsProps) {
const list = results
.map(({name, description}) =>
<div>
<p>username: {name}</p>
<p>description: {description}</p>
</div>
)
return ( return (
<div> <div>
<p>username: {username}</p> {list}
<p>password: {password}</p>
</div> </div>
) )
} }

@ -1,16 +1,15 @@
import React from "react";
import ReactDOM from "react-dom/client";
export default function SampleForm() { export default function SampleForm() {
return ( return (
<div> <div>
<h1>Hello, this is a sample form made in react !</h1> <h1>Hello, this is a sample form made in react !</h1>
<form action="result" method="POST"> <form action="submit" method="POST">
<label>your name: </label> <label>your name: </label>
<input type="text" id="name" name="username"/> <input type="text" id="name" name="name"/>
<label>your password: </label> <label>a little description about yourself: </label>
<input type="password" id="password" name="password"/> <input type="text" id="password" name="description"/>
<input type="submit" value="click me!"/> <input type="submit" value="click me to submit!"/>
</form> </form>
</div> </div>
) )

@ -4,9 +4,17 @@ $hostname = getHostName();
$front_url = "http://$hostname:5173"; $front_url = "http://$hostname:5173";
const _SUPPORTS_FAST_REFRESH = true; const _SUPPORTS_FAST_REFRESH = true;
$_data_source_name = "sqlite:${_SERVER['DOCUMENT_ROOT']}/../dev-database.sqlite";
function _asset(string $assetURI): string { // no user and password needed for sqlite databases
const _DATABASE_USER = null;
const _DATABASE_PASSWORD = null;
function _asset(string $assetURI): string
{
global $front_url; global $front_url;
return $front_url . "/" . $assetURI; return $front_url . "/" . $assetURI;
} }

@ -5,6 +5,12 @@
require "../views-mappings.php"; require "../views-mappings.php";
const _SUPPORTS_FAST_REFRESH = false; const _SUPPORTS_FAST_REFRESH = false;
$database_file = __DIR__ . "/../database.sqlite";
$_data_source_name = "sqlite:/$database_file";
// no user and password needed for sqlite databases
const _DATABASE_USER = null;
const _DATABASE_PASSWORD = null;
function _asset(string $assetURI): string { function _asset(string $assetURI): string {

@ -2,8 +2,11 @@
require "../vendor/autoload.php"; require "../vendor/autoload.php";
require "../config.php"; require "../config.php";
require "../sql/database.php";
use App\Connexion;
use App\Controller\SampleFormController; use App\Controller\SampleFormController;
use App\Gateway\FormResultGateway;
/** /**
* relative path of the index.php's directory from the server's document root. * relative path of the index.php's directory from the server's document root.
@ -21,14 +24,15 @@ function get_base_path() {
} }
$basePath = get_base_path(); $basePath = get_base_path();
$con = new Connexion(get_database());
// routes initialization // routes initialization
$router = new AltoRouter(); $router = new AltoRouter();
$router->setBasePath($basePath); $router->setBasePath($basePath);
$sampleFormController = new SampleFormController(); $sampleFormController = new SampleFormController(new FormResultGateway($con));
$router->map("GET", "/", fn() => $sampleFormController->displayForm()); $router->map("GET", "/", fn() => $sampleFormController->displayForm());
$router->map("POST", "/result", fn() => $sampleFormController->displayResults($_POST)); $router->map("POST", "/submit", fn() => $sampleFormController->submitForm($_POST));
$match = $router->match(); $match = $router->match();

@ -0,0 +1,30 @@
<?php
/**
* @return PDO The PDO instance of the configuration's database connexion.
*/
function get_database(): PDO {
// defined by profiles.
global $data_source_name;
$pdo = new PDO($data_source_name, DATABASE_USER, DATABASE_PASSWORD);
$database_exists = $pdo->query("SELECT COUNT(*) FROM sqlite_master WHERE type = 'table'")->fetchColumn() > 0;
if ($database_exists) {
return $pdo;
}
foreach (scandir(__DIR__) as $file) {
if (preg_match("/.*\.sql$/i", $file)) {
$content = file_get_contents(__DIR__ . "/" . $file);
$pdo->exec($content);
}
}
maxime.batista marked this conversation as resolved
Review
- 
-             foreach (preg_split("/;\s*/", $content) as $req) {
-                 if ($req === "")
-                     break;
-                 $pdo->query($req);
-             }
+             $pdo->exec($content);
```diff - - foreach (preg_split("/;\s*/", $content) as $req) { - if ($req === "") - break; - $pdo->query($req); - } + $pdo->exec($content); ```
return $pdo;
}

@ -0,0 +1,8 @@
-- drop tables here
DROP TABLE IF EXISTS FormEntries;
CREATE TABLE FormEntries(name varchar, description varchar);

@ -0,0 +1,47 @@
<?php
namespace App;
use \PDO;
class Connexion {
private PDO $pdo;
/**
* @param PDO $pdo
*/
public function __construct(PDO $pdo)
{
$this->pdo = $pdo;
}
/**
* execute a request
* @param string $query
* @param array $args
* @return void
*/
public function exec(string $query, array $args) {
$stmnt = $this->pdo->prepare($query);
foreach ($args as $name => $value) {
$stmnt->bindValue($name, $value[0], $value[1]);
}
$stmnt->execute();
}
/**
* Execute a request, and return the returned rows
* @param string $query the SQL request
* @param array $args an array containing the arguments label, value and type: ex: `[":label" => [$value, PDO::PARAM_TYPE]`
* @return array the returned rows of the request
*/
public function fetch(string $query, array $args): array {
$stmnt = $this->pdo->prepare($query);
foreach ($args as $name => $value) {
$stmnt->bindValue($name, $value[0], $value[1]);
}
$stmnt->execute();
return $stmnt->fetchAll();
}
}

@ -3,13 +3,28 @@
namespace App\Controller; namespace App\Controller;
require_once __DIR__ . "/../react-display.php"; require_once __DIR__ . "/../react-display.php";
use App\Gateway\FormResultGateway;
class SampleFormController { class SampleFormController {
private FormResultGateway $gateway;
/**
* @param FormResultGateway $gateway
*/
public function __construct(FormResultGateway $gateway)
{
$this->gateway = $gateway;
}
public function displayForm() { public function displayForm() {
send_react_front("views/SampleForm.tsx", []); send_react_front("views/SampleForm.tsx", []);
} }
public function displayResults(array $request) { public function submitForm(array $request) {
send_react_front("views/DisplayResults.tsx", $request); $this->gateway->insert($request["name"], $request["description"]);
$results = ["results" => $this->gateway->listResults()];
send_react_front("views/DisplayResults.tsx", $results);
} }
} }

@ -0,0 +1,33 @@
<?php
namespace App\Gateway;
use PDO;
use App\Connexion;
/**
* A sample gateway, that stores the sample form's result.
*/
class FormResultGateway {
private Connexion $con;
public function __construct(Connexion $con) {
$this->con = $con;
}
function insert(string $username, string $description) {
$this->con->exec(
"INSERT INTO FormEntries VALUES (:name, :description)",
[
":name" => [$username, PDO::PARAM_STR],
"description" => [$description, PDO::PARAM_STR]
]
);
}
function listResults(): array {
return $this->con->fetch("SELECT * FROM FormEntries", []);
}
}
Loading…
Cancel
Save