SQLite: база данных

Создать таблицу, добавить запись и прочитать её.

Код

// Пример работы с базой данных SQLite через стандартную_библиотека/база_данных.код.
// Демонстрирует полный, типичный цикл: открыть базу, создать таблицу,
// вставить запись безопасным, параметризованным способом (без риска
// SQL-инъекции — значение никогда не подставляется в текст SQL напрямую),
// прочитать все записи через SELECT.

подключить база_данных;

функция главная(): целое
    результат из текста бд_результат = открыть_базу("пример.db");
    если ( не бд_результат.успешно)
        вывести("не удалось открыть базу данных");
        вернуть 1;
    конец
    текст бд = бд_результат.значение;

    результат из целого создание = выполнить_sql(бд,
        "CREATE TABLE IF NOT EXISTS пользователи (id INTEGER PRIMARY KEY, имя TEXT);");
    если ( не создание.успешно)
        вывести("ошибка создания таблицы: " + создание.сообщение);
        вернуть 1;
    конец

    // Параметризованная вставка через "?" — безопасный способ передать
    // значение, введённое пользователем (или пришедшее откуда угодно
    // извне), без риска SQL-инъекции. Простая склейка строк ("... VALUES
    // ('" + имя + "')") была бы опасна именно этим — если бы "имя"
    // содержало символ кавычки или фрагмент SQL-кода, он выполнился бы
    // как часть запроса.
    текст stmt_буфер = выделить_память(8);
    sqlite_подготовить(бд, "INSERT INTO пользователи (имя) VALUES (?);", целое32(-1), stmt_буфер, нулевой_указатель_бд());
    текст stmt_вставки = прочитать_указатель(stmt_буфер, 0);
    // целое(-1) — SQLITE_TRANSIENT, говорит SQLite самой скопировать
    // строку себе (безопаснее, чем вручную следить за временем жизни
    // исходного буфера).
    sqlite_привязать_текст(stmt_вставки, целое32(1), "Никита", целое32(-1), целое(-1));
    sqlite_шаг(stmt_вставки);
    sqlite_завершить(stmt_вставки);
    освободить_память(stmt_буфер);

    вывести("запись добавлена, читаем все записи:");

    текст stmt_буфер_select = выделить_память(8);
    sqlite_подготовить(бд, "SELECT id, имя FROM пользователи;", целое32(-1), stmt_буфер_select, нулевой_указатель_бд());
    текст stmt_выборки = прочитать_указатель(stmt_буфер_select, 0);

    целое32 шаг = sqlite_шаг(stmt_выборки);
    пока (шаг == целое32(100))  // 100 = SQLITE_ROW — есть ещё строка
        целое32 id = sqlite_колонка_целое(stmt_выборки, целое32(0));
        текст имя = sqlite_колонка_текст(stmt_выборки, целое32(1));
        // НОВОЕ: строка собирается в промежуточную переменную, а не
        // передаётся в "вывести(...)" прямой конкатенацией — известное,
        // честно задокументированное ограничение ARC для текста (см.
        // "Известные ограничения" в ДОКУМЕНТАЦИЯ_ЯЗЫКА.md): результат
        // конкатенации, переданный напрямую в вызов функции без
        // промежуточной переменной, не попадает под отслеживание ARC и
        // не освобождается — не крах, просто небольшая, безопасная утечка.
        текст строка_вывода = "  id=" + целое_в_текст(целое(id)) + ", имя=" + имя;
        вывести(строка_вывода);
        шаг = sqlite_шаг(stmt_выборки);
    конец
    sqlite_завершить(stmt_выборки);
    освободить_память(stmt_буфер_select);

    sqlite_закрыть(бд);
    вернуть 0;
конец

Как запустить

Сохраните код в файл, например база_данных_пример.код, и выполните:

запустить база_данных_пример.код

Как это работает

  • подключить база_данных; добавляет обёртку над SQLite.
  • Значения передаются через ? и привязку параметров, а не склейкой строк: так нет риска SQL-инъекции.
  • Каждый шаг (открыть, создать таблицу, вставить) возвращает результат, и ошибки проверяются сразу.

Исходник лежит в репозитории: examples/веб/база_данных_пример.код.