flang компилятор доказывает, что программа не зациклится 0.6.2 GitHub English

Базы данных

С языком идут два драйвера: PostgreSQL по проводу и чтение файла SQLite. Оба написаны на самом flang, оба проверяются примерами без всякой базы.

Кто носит байты

Программа на flang не открывает ни сокетов, ни файлов. Она возвращает план — описание действия: «открой соединение туда», «отправь эти байты», «прочитай ответ». Описанное исполняет тот, кто запустил план.

Кто носит байты между программой и базойпрограмма на flangисполнитель планаPostgreSQLописание действиябайтыбайтыответ значением
Кто носит байты между программой и базой

Поэтому сборка сообщений и разбор ответов остаются обычными тотальными функциями, а flang check не требует сервера.

PostgreSQL: подключиться и спросить

файлчто внутристрокфункцийпримеров
flang/stdlib/wire.flangоктеты, числа в сетевом порядке, строки с нулём на конце, нарезка потока10983477
flang/stdlib/postgres.flangпротокол версии 3.0: сообщения клиента собираются, ответы сервера разбираются187167126
examples/db/postgres-plan.flangвесь разговор из пяти шагов55455

Простой запрос собирается так — взято из дерева знак в знак:

тотальная функция «Простой запрос»
  принимает запрос: строка
  возвращает «Печать»
  обеспечивает «простой запрос едет буквой Q, а вместе с длиной и завершающим нулём весит на шесть байтов больше самого запроса» разбор результат
    случай вариант «Напечатано» с текст как текст
      то (текст начинается с "Q") и притом ((«Байтов в тексте» от текст) равен (6 плюс («Байтов в тексте» от запрос)))
    случай вариант «Число непечатаемо» с значение как названо
      то названо равен (5 плюс («Байтов в тексте» от запрос))
  обеспечивает «простой запрос едет кадром Q со строкой с нулём» (не («Четыре октета печатаются» от (4 плюс («Байтов в тексте» от («Строка с нулём» от запрос))))) или (результат равен (вариант «Напечатано» с текст равным (соединить (соединить "Q" с («Четыре октета» от (4 плюс («Байтов в тексте» от («Строка с нулём» от запрос))))) с («Строка с нулём» от запрос))))
  обеспечивает «непечатаемая длина простого запроса названа числом» («Четыре октета печатаются» от (4 плюс («Байтов в тексте» от («Строка с нулём» от запрос)))) или (результат равен (вариант «Число непечатаемо» с значение равным (4 плюс («Байтов в тексте» от («Строка с нулём» от запрос)))))
  пример «запрос едет буквой Q»
    дано запрос равно "a"
    ожидается вариант «Напечатано» с текст равным "Q\u0000\u0000\u0000\u0006a\u0000"
  «Кадр» от "Q" и («Строка с нулём» от запрос)

Взято из дерева целиком, знак в знак — flang/stdlib/postgres.flang.

Проверка и примеры базы не требуют:

$ flang check flang/stdlib/postgres.flang
$ flang test flang/stdlib/postgres.flang

Самому разговору живой сервер нужен:

$ flang io examples/db/postgres-plan.flang | python3 -c \
    "import sys,json; print(json.load(sys.stdin)['result'])"
1 пуск: | | | in_hot_standby=off … server_version=17.10 server_encoding=UTF8
2 создание: INSERT 0 1| | |
3 вставка с параметрами: INSERT 0 1| | |
4 выборка: SELECT 2| | 1	Мир ; 2	dva|
5 отказ: | ERROR 42703 column "netakoykolonki" does not exist| |

Пять шагов: пуск с паролем открытым текстом, создание, вставка с параметрами ($1, $2), выборка и нарочно кривой запрос, на который сервер отвечает своим кодом. Кириллица ездит в обе стороны. Без трубы команда печатает один объект JSON: в поле result — отчёт выше, в log — каждое поручение и каждый ответ, байт за байтом.

План подключается к 127.0.0.1:55434 пользователем flang, база postgres. Адрес, порт, пользователь и пароль стоят в плане литералами: план не принимает аргументов, а программа не видит окружения. Меняются они правкой функций в начале плана.

PostgreSQL: что работает, а что нет

trust и пароль открытым текстомработает
md5, scram-sha-256нет: HMAC и PBKDF2 в библиотеке нет. План продолжает читать и ждёт
TLSнет. Разговор идёт открытым текстом — годится для базы на той же машине
типы колонок из RowDescriptionберётся только число колонок. Номер типа колонки передаёте сами
пустое значение (null)не разбирается: его длина — минус один, и разбор просит 4 294 967 295 октетов
длина отправляемого сообщениявсе четыре октета длины должны быть меньше 128; запрос добивается пробелами, 200 в запасе. Значение параметра — не больше 127 байт
один проход разборане больше 1000 сообщений
испорченный потокостанавливает разбор отдельным ответом, а не молча

SQLite: прочитать файл

flang/stdlib/sqlite.flang читает базу SQLite 3 как список октетов: образ файла приходит одним поручением Прочитать октеты из файла. Ни сервера, ни провода.

Сделайте образец сторонней sqlite3 и прочитайте его обратно:

$ python3 -c "import sqlite3,os; d='/srv/tmp/sqlite-obrazec'; os.makedirs(d,exist_ok=True); \
  c=sqlite3.connect(d+'/proba.db'); c.execute('create table люди(имя text, лет integer)'); \
  c.executemany('insert into люди values (?,?)',[('Аня',31),('Боря',44),('Вера',7)]); c.commit()"

$ flang io examples/db/sqlite-read.flang | python3 -c \
    "import sys,json; print(json.load(sys.stdin)['result'])"
магия SQLite: да
размер страницы: 4096
страниц: 2
октетов в файле: 8192
таблицы: люди
корень таблицы люди: 2
SQL: CREATE TABLE люди(имя text, лет integer)
строк: 3
1 | Аня | 31
2 | Боря | 44
3 | Вера | 7

План — examples/db/sqlite-read.flang; путь к файлу и имя таблицы стоят в нём двумя однострочными функциями: «Откуда» и «Какая таблица».

SQLite: что читается, а что нет

заголовокмагия, размер страницы, число страниц
страница-схема sqlite_masterимена таблиц, их корневые страницы, их SQL
лист b-дерева таблицыуказатели на ячейки, длина нагрузки, номер строки, сама нагрузка
запись (record)ноль, целые всех шести ширин, нули и единицы серийных типов 8 и 9, текст через UTF-8, двоичное
вещественные числа (серийный тип 7)восемь октетов отдаются как есть, вариантом «Дробное»
запись в базунет. Читающий драйвер — половина, которую можно проверить целиком, не ломая чужой файл
внутренние страницы b-дерева и переполнениенет. Они начинаются на таблице крупнее одной страницы; возвращается пусто, а не подделка. «Вид страницы» отдаёт 13 у листа таблицы и 5 у внутренней
индексы (виды страниц 2 и 10)нет: они не строки таблицы

Куда дальше