{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "61949a33",
   "metadata": {},
   "source": [
    "# 22-29 · Flask na SQLite\n",
    "\n",
    "Praktyka do sekcji [„Flask i SQLite: zapisywać dane w bazie danych” `projects/flask/todo-app/app.py`."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "447eae36",
   "metadata": {},
   "source": [
    "## Cel\n",
    "\n",
    "Zebrać małą aplikację Flask- na bazie SQLite i upewnić się, że dane przetrwają utworzenie nowego obiektu aplikacji — czyli zachowują się tak samo jak po ponownym uruchomieniu procesu."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "eac93150",
   "metadata": {},
   "source": [
    "## Sprawa robocza"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "d413696f",
   "metadata": {},
   "outputs": [],
   "source": [
    "import sqlite3\n",
    "import tempfile\n",
    "import os\n",
    "\n",
    "from flask import Flask, g, jsonify, redirect, request, url_for\n",
    "\n",
    "put_k_baze = os.path.join(tempfile.mkdtemp(), \"zadachi.db\")\n",
    "\n",
    "\n",
    "def sozdat_prilozhenie():\n",
    "    prilozhenie = Flask(__name__)\n",
    "    prilozhenie.config[\"DATABASE\"] = put_k_baze\n",
    "\n",
    "    def get_db():\n",
    "        if \"db\" not in g:\n",
    "            g.db = sqlite3.connect(prilozhenie.config[\"DATABASE\"])\n",
    "            g.db.row_factory = sqlite3.Row\n",
    "        return g.db\n",
    "\n",
    "    @prilozhenie.teardown_appcontext\n",
    "    def close_db(exception=None):\n",
    "        db = g.pop(\"db\", None)\n",
    "        if db is not None:\n",
    "            db.close()\n",
    "\n",
    "    @prilozhenie.route(\"/api/tasks\", methods=[\"GET\", \"POST\"])\n",
    "    def api_tasks():\n",
    "        db = get_db()\n",
    "        if request.method == \"POST\":\n",
    "            db.execute(\"INSERT INTO tasks (title) VALUES (?)\", (request.get_json()[\"title\"],))\n",
    "            db.commit()\n",
    "            return \"\", 201\n",
    "        stroki = db.execute(\"SELECT id, title, done FROM tasks ORDER BY id\").fetchall()\n",
    "        return jsonify([dict(s) for s in stroki])\n",
    "\n",
    "    with prilozhenie.app_context():\n",
    "        get_db().execute(\"CREATE TABLE IF NOT EXISTS tasks (id INTEGER PRIMARY KEY, title TEXT NOT NULL, done INTEGER NOT NULL DEFAULT 0)\")\n",
    "        get_db().commit()\n",
    "\n",
    "    return prilozhenie\n",
    "\n",
    "\n",
    "prilozhenie1 = sozdat_prilozhenie()\n",
    "client1 = prilozhenie1.test_client()\n",
    "client1.post(\"/api/tasks\", json={\"title\": \"Задача до перезапуска\"})\n",
    "\n",
    "otvet1 = client1.get(\"/api/tasks\")\n",
    "print(\"До «перезапуска»:\", otvet1.get_json())"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4003fdc8",
   "metadata": {},
   "source": [
    "## Sprawdzanie wyniku – nowy obiekt aplikacji widzi te same dane"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "1425242d",
   "metadata": {},
   "outputs": [],
   "source": [
    "prilozhenie2 = sozdat_prilozhenie()   # как будто процесс перезапустили\n",
    "client2 = prilozhenie2.test_client()\n",
    "\n",
    "otvet2 = client2.get(\"/api/tasks\")\n",
    "print(\"После «перезапуска»:\", otvet2.get_json())\n",
    "\n",
    "assert otvet2.get_json() == otvet1.get_json()\n",
    "assert len(otvet2.get_json()) == 1\n",
    "print(\"Верно: данные хранятся в файле базы данных, а не в памяти процесса — новый объект приложения видит их.\")"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Cartesian Python 3.14",
   "language": "python",
   "name": "cartesian-python314"
  },
  "language_info": {
   "name": "python",
   "version": "3.14.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
