Spec-Zone.ru › SQLite

C/C++ Интерфейс для SQLite версии 3 (старая версия)

Примечание: Данный документ был написан в 2004 году в качестве руководства для программистов, переходящих с использования SQLite версии 2 на SQLite версии 3. Информация в этом документе по-прежнему в значительной степени верна, однако со временем произошли многочисленные изменения и улучшения. Рекомендуется использовать следующие документы вместо этого:

  • Введение в C/C++ интерфейс SQLite
  • Справочник по C/C++ интерфейсу SQLite

C/C++ Интерфейс для SQLite версии 3

1.0 Обзор

SQLite версии 3.0 — новая версия SQLite, производная от кодовой базы SQLite 2.8.13, но с несовместимым форматом файла и API. SQLite версии 3.0 была создана для удовлетворения потребностей в следующих функциях:

  • Поддержка UTF-16.
  • Пользовательские последовательности сортировки текста.
  • Возможность хранения BLOB в индексированных столбцах.

Переход на версию 3.0 был необходим для реализации этих функций, поскольку каждая из них требует несовместимых изменений в формате файла базы данных. Одновременно были внесены и другие несовместимые изменения, такие как очистка API, исходя из предположения, что лучше всего внести все несовместимые изменения сразу.

API версии 3.0 похож на API версии 2.X, но с некоторыми важными изменениями. Наиболее заметно, префикс "sqlite_", который встречается в начале всех функций и структур данных API, изменён на "sqlite3_". Это позволяет избежать путаницы между двумя API и позволяет связывать оба API SQLite 2.X и SQLite 3.0 одновременно.

Нет единого мнения о том, каким должен быть C-тип данных для строки UTF-16. Поэтому SQLite использует универсальный тип void* для ссылки на строки UTF-16. Клиентское ПО может привести указатель void* к любому типу данных, соответствующему их системе.

2.0 C/C++ Интерфейс

API SQLite 3.0 включает 83 отдельные функции помимо нескольких структур данных и #define. (Полная ссылка на API приведена в отдельном документе.) К счастью, интерфейс не так сложен, как может показаться по его размеру. Простые программы могут обойтись всего тремя функциями: sqlite3_open(), sqlite3_exec() и sqlite3_close(). Более тонкий контроль над выполнением движка базы данных обеспечивается с помощью sqlite3_prepare_v2() для компиляции оператора SQLite в байт-код и sqlite3_step() для выполнения этого байт-кода. Семейство функций, имена которых начинаются с sqlite3_column_, используется для извлечения информации о наборе результатов запроса. Многие функции интерфейса представлены парами с версиями для UTF-8 и UTF-16. Также существует набор функций для реализации пользовательских функций SQL и пользовательских последовательностей сортировки текста.

2.1 Открытие и закрытие базы данных

   typedef struct sqlite3 sqlite3;
   int sqlite3_open(const char*, sqlite3**);
   int sqlite3_open16(const void*, sqlite3**);
   int sqlite3_close(sqlite3*);
   const char *sqlite3_errmsg(sqlite3*);
   const void *sqlite3_errmsg16(sqlite3*);
   int sqlite3_errcode(sqlite3*);

Функция sqlite3_open() возвращает целочисленный код ошибки вместо указателя на структуру sqlite3, как это было в версии 2 интерфейса. Разница между sqlite3_open() и sqlite3_open16() заключается в том, что sqlite3_open16() принимает UTF-16 (в порядке байтов хост-системы) для имени файла базы данных. Если требуется создать новый файл базы данных, то sqlite3_open16() устанавливает внутреннее текстовое представление в UTF-16, а sqlite3_open() — в UTF-8.

Открытие и/или создание файла базы данных откладывается до фактической необходимости в нём. Это позволяет устанавливать опции и параметры, такие как внутреннее представление текста и размер страницы по умолчанию, с помощью инструкций PRAGMA.

Функция sqlite3_errcode() возвращает код результата для последнего основного вызова API. sqlite3_errmsg() возвращает текстовое сообщение об ошибке на английском языке для последней ошибки. Сообщение об ошибке представлено в UTF-8 и будет временным — оно может исчезнуть при следующем вызове любой функции API SQLite. sqlite3_errmsg16() работает подобно sqlite3_errmsg(), за исключением того, что возвращает сообщение об ошибке, представленное как UTF-16 в порядке байтов хост-системы.

Коды ошибок для SQLite версии 3 не изменены по сравнению с версией 2. Они следующие:

#define SQLITE_OK           0   /* Successful result */
#define SQLITE_ERROR        1   /* SQL error or missing database */
#define SQLITE_INTERNAL     2   /* An internal logic error in SQLite */
#define SQLITE_PERM         3   /* Access permission denied */
#define SQLITE_ABORT        4   /* Callback routine requested an abort */
#define SQLITE_BUSY         5   /* The database file is locked */
#define SQLITE_LOCKED       6   /* A table in the database is locked */
#define SQLITE_NOMEM        7   /* A malloc() failed */
#define SQLITE_READONLY     8   /* Attempt to write a readonly database */
#define SQLITE_INTERRUPT    9   /* Operation terminated by sqlite_interrupt() */
#define SQLITE_IOERR       10   /* Some kind of disk I/O error occurred */
#define SQLITE_CORRUPT     11   /* The database disk image is malformed */
#define SQLITE_NOTFOUND    12   /* (Internal Only) Table or record not found */
#define SQLITE_FULL        13   /* Insertion failed because database is full */
#define SQLITE_CANTOPEN    14   /* Unable to open the database file */
#define SQLITE_PROTOCOL    15   /* Database lock protocol error */
#define SQLITE_EMPTY       16   /* (Internal Only) Database table is empty */
#define SQLITE_SCHEMA      17   /* The database schema changed */
#define SQLITE_TOOBIG      18   /* Too much data for one row of a table */
#define SQLITE_CONSTRAINT  19   /* Abort due to contraint violation */
#define SQLITE_MISMATCH    20   /* Data type mismatch */
#define SQLITE_MISUSE      21   /* Library used incorrectly */
#define SQLITE_NOLFS       22   /* Uses OS features not supported on host */
#define SQLITE_AUTH        23   /* Authorization denied */
#define SQLITE_ROW         100  /* sqlite_step() has another row ready */
#define SQLITE_DONE        101  /* sqlite_step() has finished executing */

2.2 Выполнение операторов SQL

   typedef int (*sqlite_callback)(void*,int,char**, char**);
   int sqlite3_exec(sqlite3*, const char *sql, sqlite_callback, void*, char**);

Функция sqlite3_exec() работает примерно так же, как и в SQLite версии 2. Ноль или более операторов SQL, указанных во втором параметре, компилируются и выполняются. Результаты запросов возвращаются в функцию обратного вызова.

В SQLite версии 3 функция sqlite3_exec является просто обёрткой вокруг вызовов интерфейса подготовленных операторов.

   typedef struct sqlite3_stmt sqlite3_stmt;
   int sqlite3_prepare(sqlite3*, const char*, int, sqlite3_stmt**, const char**);
   int sqlite3_prepare16(sqlite3*, const void*, int, sqlite3_stmt**, const void**);
   int sqlite3_finalize(sqlite3_stmt*);
   int sqlite3_reset(sqlite3_stmt*);

Интерфейс sqlite3_prepare компилирует один оператор SQL в байт-код для последующего выполнения. Этот интерфейс теперь является предпочтительным способом доступа к базе данных.

Оператор SQL — строка UTF-8 для sqlite3_prepare(). sqlite3_prepare16() работает аналогично, за исключением того, что ожидает строку UTF-16 в качестве входных данных SQL. Компилируется только первый оператор SQL в входной строке. В пятом параметре заполняется указатель на следующий (нескомпилированный) оператор SQLite в входной строке, если таковой имеется. Функция sqlite3_finalize() освобождает подготовленный оператор SQL. Все подготовленные операторы должны быть завершены перед закрытием базы данных. Функция sqlite3_reset() сбрасывает подготовленный оператор SQL, чтобы его можно было выполнить снова.

Оператор SQL может содержать токены вида "?" или "?nnn" или ":aaa", где "nnn" — целое число, а "aaa" — идентификатор. Такие токены представляют собой неопределённые значения литералов (или "подстановки"), которые будут заполнены позже интерфейсом sqlite3_bind. Каждый токен подстановки имеет связанный номер, который соответствует его порядковому номеру в операторе или "nnn" в случае "?nnn". Разрешается один и тот же токен подстановки встречаться более одного раза в одном операторе SQL, в этом случае все экземпляры этого токена будут заполнены одним и тем же значением. Несвязанные токены подстановки имеют значение NULL.

   int sqlite3_bind_blob(sqlite3_stmt*, int, const void*, int n, void(*)(void*));
   int sqlite3_bind_double(sqlite3_stmt*, int, double);
   int sqlite3_bind_int(sqlite3_stmt*, int, int);
   int sqlite3_bind_int64(sqlite3_stmt*, int, long long int);
   int sqlite3_bind_null(sqlite3_stmt*, int);
   int sqlite3_bind_text(sqlite3_stmt*, int, const char*, int n, void(*)(void*));
   int sqlite3_bind_text16(sqlite3_stmt*, int, const void*, int n, void(*)(void*));
   int sqlite3_bind_value(sqlite3_stmt*, int, const sqlite3_value*);

Существует набор функций sqlite3_bind для назначения значений токенам подстановки в подготовленном операторе SQL. Несвязанные токены подстановки интерпретируются как NULL. Связывания не сбрасываются функцией sqlite3_reset(). Но токены подстановки могут быть повторно привязаны к новым значениям после sqlite3_reset().

После подготовки оператора SQL (и необязательно привязки) он выполняется с помощью:

   int sqlite3_step(sqlite3_stmt*);

Функция sqlite3_step() возвращает SQLITE_ROW, если она возвращает один ряд набора результатов, или SQLITE_DONE, если выполнение завершено, либо нормально, либо из-за ошибки. Она также может вернуть SQLITE_BUSY, если не удаётся открыть файл базы данных. Если возвращаемое значение равно SQLITE_ROW, то можно использовать следующие функции для извлечения информации об этом ряде набора результатов:

   const void *sqlite3_column_blob(sqlite3_stmt*, int iCol);
   int sqlite3_column_bytes(sqlite3_stmt*, int iCol);
   int sqlite3_column_bytes16(sqlite3_stmt*, int iCol);
   int sqlite3_column_count(sqlite3_stmt*);
   const char *sqlite3_column_decltype(sqlite3_stmt *, int iCol);
   const void *sqlite3_column_decltype16(sqlite3_stmt *, int iCol);
   double sqlite3_column_double(sqlite3_stmt*, int iCol);
   int sqlite3_column_int(sqlite3_stmt*, int iCol);
   long long int sqlite3_column_int64(sqlite3_stmt*, int iCol);
   const char *sqlite3_column_name(sqlite3_stmt*, int iCol);
   const void *sqlite3_column_name16(sqlite3_stmt*, int iCol);
   const unsigned char *sqlite3_column_text(sqlite3_stmt*, int iCol);
   const void *sqlite3_column_text16(sqlite3_stmt*, int iCol);
   int sqlite3_column_type(sqlite3_stmt*, int iCol);

Функция sqlite3_column_count() возвращает количество столбцов в наборе результатов. Функция sqlite3_column_count() может быть вызвана в любое время после sqlite3_prepare_v2(). Функция sqlite3_data_count() работает аналогично функции sqlite3_column_count(), за исключением того, что она работает только после sqlite3_step(). Если предыдущий вызов sqlite3_step() вернул SQLITE_DONE или код ошибки, то sqlite3_data_count() вернёт 0, тогда как sqlite3_column_count() продолжит возвращать количество столбцов в наборе результатов.

Полученные данные проверяются с помощью других функций sqlite3_column_***(), все из которых принимают номер столбца в качестве второго параметра. Номера столбцов нумеруются от нуля слева направо. Обратите внимание, что это отличается от параметров, которые нумеруются, начиная с единицы.

Функция sqlite3_column_type() возвращает тип данных значения в N-м столбце. Возвращаемое значение — одно из следующих:

   #define SQLITE_INTEGER  1
   #define SQLITE_FLOAT    2
   #define SQLITE_TEXT     3
   #define SQLITE_BLOB     4
   #define SQLITE_NULL     5

Функция sqlite3_column_decltype() возвращает текст, который является объявленным типом столбца в операторе CREATE TABLE. Для выражения возвращаемый тип — пустая строка. sqlite3_column_name() возвращает имя N-го столбца. sqlite3_column_bytes() возвращает количество байтов в столбце типа BLOB или количество байтов в текстовой строке с кодировкой UTF-8. sqlite3_column_bytes16() возвращает то же значение для BLOB, а для текстовых строк возвращает количество байтов в кодировке UTF-16. sqlite3_column_blob() возвращает данные BLOB. sqlite3_column_text() возвращает данные TEXT в формате UTF-8. sqlite3_column_text16() возвращает данные TEXT в формате UTF-16. sqlite3_column_int() возвращает целочисленные данные в формате целых чисел хост-машины. sqlite3_column_int64() возвращает 64-битные целые данные. И, наконец, sqlite3_column_double() возвращает данные с плавающей запятой.

Нет необходимости извлекать данные в формате, указанном в sqlite3_column_type(). Если требуется другой формат, данные преобразуются автоматически.

Преобразования форматов данных могут привести к тому, что указатель, возвращённый предыдущими вызовами sqlite3_column_blob(), sqlite3_column_text() и/или sqlite3_column_text16(), станут недействительными. Указатели могут стать недействительными в следующих случаях:

  • Изначальное содержимое — BLOB, и вызывается sqlite3_column_text() или sqlite3_column_text16(). Строке может потребоваться добавить нуль-терминатор.

  • Изначальное содержимое — текст UTF-8, и вызываются sqlite3_column_bytes16() или sqlite3_column_text16(). Содержимое должно быть преобразовано в UTF-16.

  • Изначальное содержимое — текст UTF-16, и вызываются sqlite3_column_bytes() или sqlite3_column_text(). Содержимое должно быть преобразовано в UTF-8.

Обратите внимание, что преобразования между UTF-16be и UTF-16le всегда выполняются на месте и не приводят к аннулированию предыдущего указателя, хотя, разумеется, содержимое буфера, на который указывает предыдущий указатель, будет изменено. Другие виды преобразований выполняются на месте, когда это возможно, но иногда это невозможно, и в таких случаях предыдущие указатели аннулируются.

Наиболее безопасная и лёгкая в запоминании политика — предположить, что любой результат из

  • sqlite3_column_blob(),
  • sqlite3_column_text() или
  • sqlite3_column_text16()
аннулируется последующими вызовами
  • sqlite3_column_bytes(),
  • sqlite3_column_bytes16(),
  • sqlite3_column_text() или
  • sqlite3_column_text16().
Это означает, что вы всегда должны вызвать sqlite3_column_bytes() или sqlite3_column_bytes16() перед вызовом sqlite3_column_blob(), sqlite3_column_text() или sqlite3_column_text16().

2.3 Пользовательские функции

Пользовательские функции могут быть созданы с помощью следующей функции:

   typedef struct sqlite3_value sqlite3_value;
   int sqlite3_create_function(
     sqlite3 *,
     const char *zFunctionName,
     int nArg,
     int eTextRep,
     void*,
     void (*xFunc)(sqlite3_context*,int,sqlite3_value**),
     void (*xStep)(sqlite3_context*,int,sqlite3_value**),
     void (*xFinal)(sqlite3_context*)
   );
   int sqlite3_create_function16(
     sqlite3*,
     const void *zFunctionName,
     int nArg,
     int eTextRep,
     void*,
     void (*xFunc)(sqlite3_context*,int,sqlite3_value**),
     void (*xStep)(sqlite3_context*,int,sqlite3_value**),
     void (*xFinal)(sqlite3_context*)
   );
   #define SQLITE_UTF8     1
   #define SQLITE_UTF16    2
   #define SQLITE_UTF16BE  3
   #define SQLITE_UTF16LE  4
   #define SQLITE_ANY      5

Параметр nArg указывает количество аргументов функции. Значение 0 означает, что разрешено любое количество аргументов. Параметр eTextRep указывает, в каком представлении ожидаются текстовые значения аргументов для этой функции. Это значение должно быть одним из определённых выше параметров. SQLite версии 3 допускает несколько реализаций одной и той же функции с использованием различных текстовых представлений. Движок базы данных выбирает функцию, минимизирующую количество необходимых преобразований текста.

Нормальные функции указывают только xFunc и оставляют xStep и xFinal равными NULL. Агрегированные функции указывают xStep и xFinal и оставляют xFunc равным NULL. Нет отдельного API sqlite3_create_aggregate().

Имя функции задается в формате UTF-8. Отдельный API sqlite3_create_function16() работает так же, как sqlite_create_function(), за исключением того, что имя функции задается в формате UTF-16 в порядке байтов хоста.

Обратите внимание, что параметры функций теперь являются указателями на структуры sqlite3_value, а не на указатели на строки, как в SQLite версии 2.X. Следующие процедуры используются для извлечения полезной информации из этих «значений»:

   const void *sqlite3_value_blob(sqlite3_value*);
   int sqlite3_value_bytes(sqlite3_value*);
   int sqlite3_value_bytes16(sqlite3_value*);
   double sqlite3_value_double(sqlite3_value*);
   int sqlite3_value_int(sqlite3_value*);
   long long int sqlite3_value_int64(sqlite3_value*);
   const unsigned char *sqlite3_value_text(sqlite3_value*);
   const void *sqlite3_value_text16(sqlite3_value*);
   int sqlite3_value_type(sqlite3_value*);

Реализации функций используют следующие API для получения контекста и отчета о результатах:

   void *sqlite3_aggregate_context(sqlite3_context*, int nbyte);
   void *sqlite3_user_data(sqlite3_context*);
   void sqlite3_result_blob(sqlite3_context*, const void*, int n, void(*)(void*));
   void sqlite3_result_double(sqlite3_context*, double);
   void sqlite3_result_error(sqlite3_context*, const char*, int);
   void sqlite3_result_error16(sqlite3_context*, const void*, int);
   void sqlite3_result_int(sqlite3_context*, int);
   void sqlite3_result_int64(sqlite3_context*, long long int);
   void sqlite3_result_null(sqlite3_context*);
   void sqlite3_result_text(sqlite3_context*, const char*, int n, void(*)(void*));
   void sqlite3_result_text16(sqlite3_context*, const void*, int n, void(*)(void*));
   void sqlite3_result_value(sqlite3_context*, sqlite3_value*);
   void *sqlite3_get_auxdata(sqlite3_context*, int);
   void sqlite3_set_auxdata(sqlite3_context*, int, void*, void (*)(void*));

2.4 Пользовательские правила сортировки

Следующие процедуры используются для реализации пользовательских правил сортировки:

   sqlite3_create_collation(sqlite3*, const char *zName, int eTextRep, void*,
      int(*xCompare)(void*,int,const void*,int,const void*));
   sqlite3_create_collation16(sqlite3*, const void *zName, int eTextRep, void*,
      int(*xCompare)(void*,int,const void*,int,const void*));
   sqlite3_collation_needed(sqlite3*, void*, 
      void(*)(void*,sqlite3*,int eTextRep,const char*));
   sqlite3_collation_needed16(sqlite3*, void*,
      void(*)(void*,sqlite3*,int eTextRep,const void*));

Функция sqlite3_create_collation() задает имя правила сортировки и функцию сравнения для реализации этого правила сортировки. Функция сравнения используется только для сравнения текстовых значений. Параметр eTextRep может принимать значения SQLITE_UTF8, SQLITE_UTF16LE, SQLITE_UTF16BE или SQLITE_ANY, чтобы указать, с какой текстовой кодировкой работает функция сравнения. Для одного правила сортировки могут существовать отдельные функции сравнения для каждой из текстовых кодировок UTF-8, UTF-16LE и UTF-16BE. Функция sqlite3_create_collation16() работает аналогично sqlite3_create_collation(), за исключением того, что имя правила сортировки задается в формате UTF-16 в порядке байтов хоста вместо UTF-8.

Процедура sqlite3_collation_needed() регистрирует обратный вызов, который движок базы данных будет вызывать, если он столкнется с неизвестным правилом сортировки. Обратный вызов может найти подходящую функцию сравнения и вызвать sqlite_3_create_collation() по мере необходимости. Четвертый параметр обратного вызова — имя правила сортировки в формате UTF-8. Для sqlite3_collation_need16() обратный вызов получает имя правила сортировки в формате UTF-16 в порядке байтов хоста.

Последнее изменение этой страницы: 2022-01-08 05:02:57 UTC

SQLite is in the Public Domain.
https://sqlite.org/capi3.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API