added db transactions
This commit is contained in:
BIN
build/slides.pdf
BIN
build/slides.pdf
Binary file not shown.
BIN
slides.pdf
BIN
slides.pdf
Binary file not shown.
88
slides.tex
88
slides.tex
@@ -43,7 +43,9 @@
|
|||||||
\maketitle
|
\maketitle
|
||||||
|
|
||||||
\begin{frame}{Introduction}
|
\begin{frame}{Introduction}
|
||||||
...
|
\begin{center}
|
||||||
|
\url{https://info-demo-sor.univ-brest.fr}
|
||||||
|
\end{center}
|
||||||
\end{frame}
|
\end{frame}
|
||||||
|
|
||||||
\begin{framefont}{\small}
|
\begin{framefont}{\small}
|
||||||
@@ -67,7 +69,7 @@
|
|||||||
\item Objectifs :
|
\item Objectifs :
|
||||||
\begin{itemize}
|
\begin{itemize}
|
||||||
\item Développer une application suivant l'\textbf{architecture trois tiers}, s'appuyant sur des communications via \textbf{HTTP} et \textbf{WebSockets} ;
|
\item Développer une application suivant l'\textbf{architecture trois tiers}, s'appuyant sur des communications via \textbf{HTTP} et \textbf{WebSockets} ;
|
||||||
\item Comprendre les mécanismes de l'\textbf{authentification} (avec ou sans état) d'un client auprès d'un serveur ;
|
\item Comprendre les mécanismes pour l'\textbf{authentification} (avec ou sans état) d'un client auprès d'un serveur ;
|
||||||
\item S'initier au \textbf{déploiement} d'une application répartie à l'aide d'un \textit{reverse proxy}.
|
\item S'initier au \textbf{déploiement} d'une application répartie à l'aide d'un \textit{reverse proxy}.
|
||||||
\end{itemize}
|
\end{itemize}
|
||||||
\item Prérequis :
|
\item Prérequis :
|
||||||
@@ -111,7 +113,8 @@
|
|||||||
\item Persistance
|
\item Persistance
|
||||||
\begin{itemize}
|
\begin{itemize}
|
||||||
\item Base de données
|
\item Base de données
|
||||||
\item Cache
|
\item Transactions
|
||||||
|
% \item Cache
|
||||||
\end{itemize}
|
\end{itemize}
|
||||||
\end{itemize}
|
\end{itemize}
|
||||||
\item Protocoles
|
\item Protocoles
|
||||||
@@ -148,7 +151,7 @@
|
|||||||
\item Langage (TypeScript)
|
\item Langage (TypeScript)
|
||||||
\item Framework (Oak)
|
\item Framework (Oak)
|
||||||
\item Base de données (SQLite)
|
\item Base de données (SQLite)
|
||||||
\item Cache (Redis)
|
% \item Cache (Redis)
|
||||||
\end{itemize}
|
\end{itemize}
|
||||||
\item Côté client :
|
\item Côté client :
|
||||||
\begin{itemize}
|
\begin{itemize}
|
||||||
@@ -304,6 +307,8 @@
|
|||||||
\begin{itemize}
|
\begin{itemize}
|
||||||
\item \textit{The TypeScript Handbook}~\footnote{\fullcite{HandbookTypeScriptHandbook}}
|
\item \textit{The TypeScript Handbook}~\footnote{\fullcite{HandbookTypeScriptHandbook}}
|
||||||
\item \textit{The Concise TypeScript Book}~\footnote{\fullcite{poggialiConciseTypeScriptBook2026}}
|
\item \textit{The Concise TypeScript Book}~\footnote{\fullcite{poggialiConciseTypeScriptBook2026}}
|
||||||
|
\item TypeScript TV~\footnote[frame]{\url{https://typescript.tv/}} (liste des codes d'erreur)
|
||||||
|
\item TS Playground~\footnote[frame]{\url{https://www.typescriptlang.org/play/}} (environnement d'exécution en ligne)
|
||||||
\end{itemize}
|
\end{itemize}
|
||||||
\end{itemize}
|
\end{itemize}
|
||||||
\end{frame}
|
\end{frame}
|
||||||
@@ -314,13 +319,13 @@
|
|||||||
\item \texttt{boolean}
|
\item \texttt{boolean}
|
||||||
\item \texttt{number}
|
\item \texttt{number}
|
||||||
\item \texttt{string}
|
\item \texttt{string}
|
||||||
\item Tableaux (dynamiques) : \texttt{type[]} ou \texttt{Array<type>}
|
\item Tableaux (dynamiques) -- exemple : \texttt{string[]} ou \texttt{Array<string>}
|
||||||
\item Tuples (taille fixe) : \texttt{let x: [string, number]}
|
\item Tuples (taille fixe) -- exemple : \texttt{let x: [string, number]}
|
||||||
\item \texttt{enum}
|
\item \texttt{enum}
|
||||||
\item \texttt{unknown}
|
\item \texttt{unknown} (type à préciser en le vérifiant à l'exécution)
|
||||||
\item \texttt{any}
|
\item \texttt{any} (à éviter : toute valeur autorisée)
|
||||||
\item \texttt{void}
|
\item \texttt{void} (absence de valeur)
|
||||||
\item \texttt{null} et \texttt{undefined}
|
\item \texttt{null} (valeur vide) et \texttt{undefined} (valeur non définie)
|
||||||
\end{itemize}
|
\end{itemize}
|
||||||
\end{frame}
|
\end{frame}
|
||||||
|
|
||||||
@@ -377,6 +382,21 @@ console.log(o.other);
|
|||||||
\end{minted}
|
\end{minted}
|
||||||
\end{frame}
|
\end{frame}
|
||||||
|
|
||||||
|
\begin{frame}[fragile]{TypeScript : typer les objets avec \texttt{Record}}
|
||||||
|
\begin{minted}{js}
|
||||||
|
const o: Record<string, string | number | boolean> = {
|
||||||
|
"foo": "bar",
|
||||||
|
"value": 42,
|
||||||
|
other: true,
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(o.foo);
|
||||||
|
console.log(o["value"]);
|
||||||
|
console.log(o.other);
|
||||||
|
console.log(o.blabla); // undefined
|
||||||
|
\end{minted}
|
||||||
|
\end{frame}
|
||||||
|
|
||||||
\begin{frame}[fragile]{Typage, interfaces et classes}
|
\begin{frame}[fragile]{Typage, interfaces et classes}
|
||||||
\begin{columns}
|
\begin{columns}
|
||||||
\column{.5\textwidth}
|
\column{.5\textwidth}
|
||||||
@@ -1118,6 +1138,53 @@ CREATE TABLE thing_options (
|
|||||||
\end{minted}
|
\end{minted}
|
||||||
\end{frame}
|
\end{frame}
|
||||||
|
|
||||||
|
\begin{frame}[fragile]{Base de données : transactions}
|
||||||
|
\begin{itemize}
|
||||||
|
\item \textbf{Interdépendance} (sémantique et/ou fonctionnelle) entre deux requêtes \textbf{distinctes}
|
||||||
|
\item Les deux doivent réussir ou échouer \textbf{ensemble} pour éviter une \textbf{incohérence dans l'état} de l'application
|
||||||
|
\end{itemize}
|
||||||
|
|
||||||
|
\vspace{.5cm}
|
||||||
|
|
||||||
|
\begin{minted}[fontsize=\footnotesize]{ts}
|
||||||
|
// Persist vote
|
||||||
|
const voteId = crypto.randomUUID();
|
||||||
|
const now = new Date().toISOString();
|
||||||
|
db.prepare(
|
||||||
|
"INSERT INTO votes " +
|
||||||
|
"(id, poll_id, option_id, user_id, created_at) " +
|
||||||
|
"VALUES (?, ?, ?, ?, ?);",
|
||||||
|
).run(voteId, pollId, optionId, userId || null, now);
|
||||||
|
|
||||||
|
// Increment tally
|
||||||
|
db.prepare(
|
||||||
|
"UPDATE poll_options SET vote_count = vote_count + 1 WHERE id = ?;",
|
||||||
|
).run(optionId);
|
||||||
|
\end{minted}
|
||||||
|
\end{frame}
|
||||||
|
|
||||||
|
\begin{frame}[fragile]{Base de données : transactions}
|
||||||
|
\begin{itemize}
|
||||||
|
\item Mécanisme : \textbf{transactions}
|
||||||
|
\item Unités de travail qui garantissent l'\textbf{atomicité} des opérations
|
||||||
|
\end{itemize}
|
||||||
|
|
||||||
|
\vspace{.5cm}
|
||||||
|
|
||||||
|
\begin{minted}{ts}
|
||||||
|
try {
|
||||||
|
db.prepare("BEGIN").run(); // Start transaction
|
||||||
|
|
||||||
|
db.prepare("...").run(); // Query 1
|
||||||
|
db.prepare("...").run(); // Query 2
|
||||||
|
|
||||||
|
db.prepare("COMMIT").run(); // Commit transaction
|
||||||
|
} catch {
|
||||||
|
db.prepare("ROLLBACK").run(); // Rollback on any error
|
||||||
|
}
|
||||||
|
\end{minted}
|
||||||
|
\end{frame}
|
||||||
|
|
||||||
\begin{frame}[fragile]{Tests}
|
\begin{frame}[fragile]{Tests}
|
||||||
\begin{minted}{ts}
|
\begin{minted}{ts}
|
||||||
import { assertEquals, assert } from "@std/assert";
|
import { assertEquals, assert } from "@std/assert";
|
||||||
@@ -1159,6 +1226,7 @@ Deno.test({
|
|||||||
\item \texttt{useParams}
|
\item \texttt{useParams}
|
||||||
\item \texttt{useState}
|
\item \texttt{useState}
|
||||||
\item \texttt{useRef}
|
\item \texttt{useRef}
|
||||||
|
\item \texttt{useEffect}
|
||||||
\end{itemize}
|
\end{itemize}
|
||||||
\item Functional Components
|
\item Functional Components
|
||||||
\item React Router
|
\item React Router
|
||||||
|
|||||||
Reference in New Issue
Block a user