![]() |
|
|||
WebMoney: WMZ Z294115950220 WMR R409981405661 WME E134003968233 |
Visa 4274 3200 2453 6495 |
Библиотека SQLite разработана, чтобы быть очень простой в использовании
из программы C++ или C. Этот документ дает
обзор интерфейса программирования C/C++. Интерфейс в библиотеку SQLite состоит из трех основных функций, одной
непрозрачной структуры данных и некоторых констант, используемых в качестве
возвращаемых значений. Основной интерфейс: Вышеупомянутое это все, что действительно необходимо знать, чтобы
использовать SQLite в программах C или C++. Есть другие доступные функции
интерфейса, но мы начнем, описывая основные функции, показанные выше. Используйте функцию sqlite_open, чтобы открыть существующую базу
данных SQLite или создать новую базу данных SQLite. Первый аргумент это имя
базы данных. Второй аргумент предназначается, чтобы сигнализировать, будет ли
база данных используемой для чтения и записи или только для чтения.
Но в текущем внедрении проигнорирован второй аргумент sqlite_open.
Третий аргумент это указатель на указатель строки. Если третьим аргументом не
будет NULL, и ошибка происходит, пытаясь открыть базу данных, то сообщение об
ошибке будет написано в память, полученную из malloc() и *errmsg
будет сделан так, чтобы указать на это сообщение об ошибке.
Функция запроса ответственна за освобождение памяти, когда
это закончит работу. Название базы данных SQLite это название файла, который будет содержать
базу данных. Если файл не существует, SQLite пытается создать и
инициализировать его. Если файл только для чтения (из-за полномочий или
потому что он расположен на CD-ROM), SQLite открывает базу данных для чтения
только. Вся база данных SQL сохранена в единственном файле на диске.
Но дополнительные временные файлы могут быть созданы во время выполнения
команды SQL, чтобы сохранить журнал обратной перемотки базы данных или
временные и промежуточные результаты запроса. Возвращаемое значение функции sqlite_open
это указатель на непрозрачную структуру sqlite.
Этот указатель будет первым аргументом всем последующим вызовам функции
SQLite, которые имеют дело с той же самой базой данных.
NULL возвращен, если открытие терпит неудачу по какой-либо причине. Чтобы закрыть базу данных SQLite, вызовите функцию sqlite_close,
передавая указатель структуры, который был получен от предшествующего вызова
sqlite_open. Если транзакция активна, когда база данных
закрывается, она отменяется. Функция sqlite_exec используется, чтобы обработать SQL-операторы и
запросы. Эта функция требует 5 параметров следующим образом: Указатель на структуру sqlite, полученную от предшествующего
вызова sqlite_open. Законченная нолем последовательность, содержащая текст одного или
более SQL-операторов и/или запросов, которые будут обработаны. Указатель на функцию обратного вызова, которая вызвана однажды для
каждой строки в результате запроса. Этот аргумент может быть NULL, в этом
случае никакие отзывы никогда не будут вызываться. Указатель, который отправлен, чтобы стать первым аргументом
функции обратного вызова. Указатель на строку ошибки. Сообщения об ошибках написаны
в память, выделенную malloc(), и строка ошибки должна указать на пространство
из malloc. Функция запроса ответственна за освобождение этого пространства,
когда это закончило работу с ним. Этот аргумент может быть NULL, в этом
случае сообщения об ошибках не возвращаются функции запроса. Функция обратного вызова используется, чтобы получить результаты запроса.
Прототип для функции обратного вызова: Первый аргумент это просто копия четвертого аргумента sqlite_exec.
Этот параметр может использоваться, чтобы передать произвольную информацию
функции обратного вызова из кода клиента. Второй аргумент это количество
колонок в результате запроса. Третий аргумент это множество указателей на
последовательности, где каждая последовательность это отдельный столбец
результата для записи. Обратите внимание на то, что функция обратного
вызова сообщает NULL в базе данных как об указателе NULL,
что очень отличается от пустой строки. Если i-й параметр
будет пустой строкой: Но если i-й параметр NULL: Названия колонок содержатся в первых argc записях четвертого
аргумента. Если прагма SHOW_DATATYPES = on
(по умолчанию), вторые argc записи в 4-м аргументе это
типы данных для соответствующих колонок. Если прагма
EMPTY_RESULT_CALLBACKS = ON и результат запроса это пустое
множество, то отзыв вызван однажды с третьим параметром (argv) = 0:
Функция обратного вызова должна обычно возвращать 0.
Если результат функции обратного вызова отличен от нуля, запрос немедленно
прерывается, а sqlite_exec вернет SQLITE_ABORT. sqlite_exec обычно возвращает SQLITE_OK. Но если что-то идет не
так, как надо, это может возвратить иное значение, чтобы указать на тип
ошибки. Вот полный список кодов возврата: Значения этих возвращаемых значений следующие: Это значение возвращено, если все работало и не
было никаких ошибок. Это значение указывает что внутренняя проверка на непротиворечивость в
библиотеке SQLite провалена. Это может произойти только, если есть ошибка в
библиотеке SQLite. Если вы когда-нибудь получаете ответ SQLITE_INTERNAL от
sqlite_exec, пожалуйста, сообщите о проблеме в
списке рассылки SQLite. Это возвращаемое значение указывает, что была ошибка в SQL-запросе,
который был передан в sqlite_exec. Это возвращаемое значение говорит, что права доступа на файле базы
данных таковы, что файл не может быть открыт. Это значение возвращено если результат
функции обратного вызова отличен от нуля. Этот код возврата указывает, что другие программы или потоки
блокировали базу данных. SQLite позволяет двум или больше потокам
читать базу данных в то же время, но только у одного потока
может быть база данных, открытая для записи в то же время.
Блокировка в SQLite находится на всей базе данных. Этот код возврата подобен SQLITE_BUSY, в котором он
указывает, что база данных заблокирована. Но источник блокировки
рекурсивный вызов sqlite_exec.
Это возвращение может произойти только при попытке вызвать sqlite_exec из
работающего sqlite_exec. Рекурсивные вызовы sqlite_exec позволены, пока они
не пытаются писать ту же самую таблицу. Это значение возвращено, если malloc терпит неудачу. Этот код возврата указывает, что была предпринята попытка
писать файл базы данных, который открыт только для чтения. Это значение возвращено, если sqlite_interrupt
прерывает происходящую операцию по базе данных. Это значение возвращено, если операционная система сообщает SQLite,
что не способна выполнить некоторую операцию дискового I/O.
Это могло означать, что больше нет места на диске. Это значение возвращено, если SQLite обнаруживает, что база данных
стала испорченной. Повреждение могло бы произойти из-за процесса, пишущего
файлу базы данных, или это могло бы произойти из-за ранее необнаруженной
логической ошибки в SQLite. Это значение также возвращено, если
происходит ошибка I/O диска таким способом, что SQLite вынужден оставить файл
базы данных в поврежденном состоянии. Последнее может произойти только из-за
сбоя аппаратной или операционной системы. Это значение возвращено, если вставка потерпела неудачу, потому что
нет никакого места на диске, или база данных слишком большая, чтобы
содержать больше информации. Последний случай должен произойти только для баз
данных, которые больше, чем 2 ГБ в размере. Это значение возвращено, если файл базы данных не мог бы быть открыт
по некоторым причинам. Это значение возвращено, если некоторый другой процесс связывается с
блокировками файла и нарушил протокол блокировки файла, который SQLite
использует на его файлах журнала обратной перемотки. Когда база данных сначала открылась, SQLite читает схему базы данных в
память и использует ту схему, чтобы разобрать новые SQL-операторы.
Если другой процесс изменит схему, команда, в настоящее время обрабатываемая,
прервется, потому что произведенный код
виртуальной машины принял старую схему. Это код возврата для таких случаев.
Повторение команды обычно решает проблему. SQLite не хранит больше, чем приблизительно 1 мегабайт данных в
единственной строке таблицы. При попытке сохранить больше чем 1 мегабайт в
единственной строке вы получаете этот код возврата. Эта константа возвращена, если SQL-оператор нарушил бы
ограничение базы данных. Эта ошибка происходит, когда есть попытка вставить данные нецелого
числа в колонку, маркированную INTEGER PRIMARY KEY.
Для большинства колонок SQLite игнорирует тип данных и позволяет любому
виду данных быть сохраненным. Но колонка INTEGER PRIMARY KEY
позволяет сохранить только целочисленные данные. Эта ошибка могла бы произойти, если один или больше SQLite API
используется неправильно. Примеры неправильного использования включают запрос
sqlite_exec после того, как база данных была закрыта, используя
sqlite_close или calling sqlite_exec
с тем же самым указателем базы данных одновременно от
двух отдельных потоков. Эта ошибка означает, что у вас есть попытки создать или получить
доступ к файлу базы данных файла, который больше, что 2 ГБ на
устаревшей машине Unix. Эта ошибка указывает, что отзыв
отверг SQL, который вы пытаетесь выполнить. Это один из кодов возврата sqlite_step, который является частью
API. Это указывает, что другой ряд данных результата доступен. Это один из кодов возврата sqlite_step, который является частью
API. Это указывает, что SQL-оператор был полностью выполнен, и
можно вызвать sqlite_finalize. sqlite_exec используется, чтобы быть единственным способом
получить данные из базы данных SQLite. Но многие программисты сочли
неудобным использовать функцию обратного вызова, чтобы получить результаты.
Так начиная с версии 2.7.7 SQLite, второй интерфейс доступа доступен. Новый интерфейс использует три отдельных функции, чтобы заменить
единственную функцию sqlite_exec. Стратегия состоит в том, чтобы собрать единственный SQL-оператор,
используя sqlite_compile, затем многократно вызвать
sqlite_step, по одному разу для каждой строки вывода и наконец
вызвать sqlite_finalize, чтобы завершить работу после того, как
SQL закончил выполнение. sqlite_compile компилирует
единственный SQL-оператор (определенный вторым параметром) и производит
виртуальную машину, которая в состоянии выполнить запрос.
Первый параметр должен быть указателем на структуру sqlite, которая была
получена от предшествующего вызова sqlite_open.
Указатель на виртуальную машину сохранен в указателе, который передается
как 4-й параметр. Место, чтобы хранить виртуальную машину динамично выделено.
Чтобы избежать утечки памяти, функция запроса должна вызвать
sqlite_finalize после того, как это закончило работу.
4-й параметр может быть установлен в NULL, если с ошибкой сталкиваются
во время компиляции. Если с какими-либо ошибками сталкиваются во время компиляции, сообщение об
ошибке написано в память, полученную из malloc, 5-й параметр должен
указать на ту память. Если 5-й параметр NULL, то никакое сообщение об ошибке
не произведено. Если 5-й параметр не NULL, то функция запроса должна
избавиться от памяти, содержащей сообщение об ошибке,
вызывая sqlite_freemem. Если 2-й параметр на самом деле содержит два или больше
запроса SQL, только первый запрос собран. Это отличается от поведения
sqlite_exec, который выполняет все SQL-операторы в его входной строке.
3-й параметр sqlite_compile должен указать на первый символ
вне конца первого запроса
SQL во входе. Если 2-й параметр будет содержать только единственный
SQL-оператор, то 3-й параметр должен указать на '\000'
в конце 2-го параметра. При успехе sqlite_compile вернет SQLITE_OK.
Иначе код ошибки возвращен. После того, как виртуальная машина была произведена, используя
sqlite_compile, она выполняется одним или более вызовами
sqlite_step. Каждый sqlite_step,
кроме последнего, возвращает единственную строку результата.
Количество колонок в результате сохранено в целом числе, на которое указывает
2-й параметр. Указатель, определенный 3-м параметром, должен указать на
множество указателей на значения столбцов.
Указатель в 4-м параметре сделан указать на множество указателей на имена
столбцов и типы данных. 2-4 параметры sqlite_step
передают ту же самую информацию, как 2-4 параметры callback,
используя интерфейс sqlite_exec. С sqlite_step
информация о типе данных колонки всегда включается в 4-м параметре,
независимо от того, идет ли включена ли прагма
SHOW_DATATYPES. Каждый вызов sqlite_step возвращает код
целого числа, который указывает на то, что произошло во время этого шага.
Этот код может быть SQLITE_BUSY, SQLITE_ROW, SQLITE_DONE, SQLITE_ERROR или
SQLITE_MISUSE. Если виртуальная машина неспособна открыть файл базы данных,
потому что это заблокировано другим потоком или процессом, sqlite_step
возвратит SQLITE_BUSY. Функция запроса должна сделать некоторую другую
деятельность или спать в течение короткого срока, чтобы дать блокировке
шанс очиститься, затем снова вызвать sqlite_step.
Это может повторяться так много раз, как надо. Каждый раз, когда другая строка данных доступна,
sqlite_step вернет SQLITE_ROW. Данные о строке хранятся во множестве
указателей на последовательности, 2-й параметр должен указать
на это множество. Когда вся обработка будет завершена, sqlite_step возвратит
SQLITE_DONE или SQLITE_ERROR. SQLITE_DONE указывает, что запрос
закончен успешно, SQLITE_ERROR указывает, что была ошибка периода выполнения.
Детали ошибки получены из sqlite_finalize.
Неправильное употребление библиотеки: попытаться вызвать
sqlite_step снова после того, как это возвратило
SQLITE_DONE или SQLITE_ERROR. Когда sqlite_step вернет SQLITE_DONE или SQLITE_ERROR,
значения *pN и *pazColName установлены в количество колонок в наборе
результатов и к названиям колонок, как они возвращены SQLITE_ROW.
Это позволяет коду запроса находить количество столбцов результата, имена
столбцов и типы данных, даже если набор результатов пуст.
Параметр *pazValue всегда устанавливается в NULL, когда коды возврата
SQLITE_DONE или SQLITE_ERROR. Если SQL выполняет запрос, который не
возвращает результат (такой как INSERT или UPDATE) тогда *pN будет установлен
в ноль, а *pazColName = NULL. Если вы злоупотребите библиотекой, пытаясь вызвать sqlite_step
неуместно, то это будет делать попытку возвращения SQLITE_MISUSE.
Это может произойти, если вы вызываете sqlite_step()
на той же самой виртуальной машине в то же время от двух или больше
потоков или если вы вызываете sqlite_step() снова после того, как это
возвратило SQLITE_DONE или SQLITE_ERROR или если вы передаете
недействительный указатель виртуальной машины на sqlite_step().
Вы не должны зависеть от кода возврата SQLITE_MISUSE, чтобы указать на
ошибку. Возможно, что неправильное употребление интерфейса пройдет
необнаруженным и приведет к катастрофе программы.
SQLITE_MISUSE предназначается только как помощь для отладки, чтобы помочь вам
обнаружить неправильное использование до неудачи.
Логика обнаружения неправильного употребления, как гарантируют, не будет
работать в каждом случае. Каждая виртуальная машина, которую создает sqlite_compile,
должна в конечном счете быть передана sqlite_finalize.
sqlite_finalize() освобождает память и другие ресурсы, которые
использует виртуальная машина. Отказ вызова sqlite_finalize()
приведет к утечкам ресурсов в вашей программе. sqlite_finalize также возвращает код
результата, который указывает на успешность или неуспешность
операции SQL, которую выполнила виртуальная машина. Значение, возвращенное
sqlite_finalize(), совпадет с тем, которое было бы возвращено,
тем же самым SQL, выполненным sqlite_exec.
Возвращенное сообщение об ошибке также будет тем же самым. Приемлемо вызвать sqlite_finalize
на виртуальной машине, прежде чем sqlite_step вернет SQLITE_DONE.
Выполнение этого имеет эффект прерывания происходящей операции.
Частично завершенные изменения будут отменены, база данных вернется к ее
исходному состоянию (если альтернативный алгоритм восстановления не будет
выбран, используя ON CONFLICT в SQL).
Эффект совпадает с тем, как если бы функция обратного вызова
sqlite_exec вернула результат, отличный от нуля. Также приемлемо вызвать sqlite_finalize
на виртуальной машине, которая никогда не передавалась
sqlite_step даже однажды. Только три основных функции в разделе 1.0 нужны, чтобы использовать
SQLite. Но есть много других функций, которые
обеспечивают полезные интерфейсы: Все вышеупомянутые определения включены в
заголовочный файл "sqlite.h" в дереве исходных текстов. У каждой строки таблицы SQLite есть уникальный ключ целого числа. Если у
таблицы есть колонка, маркированная INTEGER PRIMARY KEY,
то та колонка служит ключом. Если нет никакой колонки INTEGER PRIMARY KEY,
ключ это уникальное целое число. К ключу для строки
можно получить доступ в операторе SELECT или использовать в WHERE или пункте
ORDER BY, используя любое из имен "ROWID", "OID" или "_ROWID_". Когда вы делаете вставку в таблицу, у которой нет столбца INTEGER PRIMARY
KEY или если столбец такой есть, но его значение не определяется в пункте
VALUES в insert, то ключ автоматически произведен. Можно найти значение
ключа для нового оператора INSERT, используя API
sqlite_last_insert_rowid. API sqlite_changes возвращает количество строк, которые были
вставлены, удалены или изменены, когда база данных была в последний раз
изменена. В общем использовании sqlite_changes
возвращает количество строк, вставленных, удаленных или измененных новым
вызовом sqlite_exec или начиная с нового sqlite_compile.
Но если вы вложили вызов sqlite_exec (то есть, если функция
отзыва одного sqlite_exec вызывает другой sqlite_exec)
или если вы вызываете sqlite_compile, чтобы создать новую VM в то
время, как есть другая VM, тогда значение числа, возвращенного
sqlite_changes сложнее. Число, о котором сообщают, включает любые
изменения, которые были позже отменены ROLLBACK или ABORT.
Но строки, которые удалены DROP TABLE НЕ считаются. SQLite осуществляет команду "DELETE FROM table" (без
WHERE), но при этом пересоздает таблицу.
Это намного быстрее, чем удаление элементов
индивидуально. Но это также означает, что значение sqlite_changes
будет нолем, независимо от числа элементов, которые были первоначально в
таблице. Если точное количество числа элементов удаленных необходимо,
используйте "DELETE FROM table WHERE 1". sqlite_get_table это оболочка для sqlite_exec,
которая собирает всю информацию от последовательных отзывов и пишет ее в
память, полученную из malloc(). Это функция удобства, которая позволяет
получить весь результат запроса к базе данных
единственным вызовом функции. Основной результат от sqlite_get_table это
множество указателей на последовательности. Есть один элемент в этом
множестве для каждой колонки каждой строки
в результате. Результаты NULL представляются указателем NULL.
В дополнение к регулярным данным есть добавленная строка
в начале множества, которая содержит название каждой колонки результата. Как пример, рассмотрите следующий запрос: Этот запрос возвратит имя, логин и название компьютера каждого
сотрудника, логин которого начинается с "d".
Если этот запрос представлен sqlite_get_table,
результат мог бы быть похожим на это: Заметьте, что "host" для записи "dummy" = NULL,
так как множество result[] содержит указатель
NULL в том месте. Если набор результатов запроса будет пуст, то по умолчанию
sqlite_get_table установит nrow = 0, а его параметр результата
устанавливается на NULL. Но если прагма EMPTY_RESULT_CALLBACKS = ON,
параметр результата инициализируется только к названиям колонок. Например,
рассмотрите этот вопрос, у которого есть пустой набор результатов: Поведение по умолчанию дает это: Но если EMPTY_RESULT_CALLBACKS = ON, то: Память, чтобы содержать информацию, возвращенную sqlite_get_table,
получена от malloc(). Но функция запроса не должна пытаться освободить эту
информацию непосредственно. Вместо этого передайте заполненную таблицу
sqlite_free_table, когда с таблицей закончена работа.
Безопасно вызвать sqlite_free_table с NULL, который был бы возвращен,
если набор результатов пуст. sqlite_get_table возвращает тот же самый код,
что и sqlite_exec. sqlite_interrupt может быть вызвана от другого потока или
обработчика сигнала, чтобы заставить текущую операцию по базе данных
прерваться при первой возможности. Когда это происходит,
sqlite_exec (или эквивалент) возвратит SQLITE_INTERRUPT. Следующий интерфейс к SQLite это функция удобства, используемая, чтобы
проверить, формирует ли последовательность полный SQL-оператор. Если
sqlite_complete вернет true, когда вводом является строка,
то аргумент формирует полный SQL-оператор. Нет никаких гарантий, что
синтаксис того запроса правилен, но мы, по крайней мере, знаем, что оно полно.
Если sqlite_complete вернет false,
то больше текста требуется, чтобы заканчивать SQL-оператор. В целях функции sqlite_complete SQL-оператор полон, если это
заканчивается точкой с запятой. Утилита sqlite использует функцию sqlite_complete, чтобы
знать, когда это должно вызвать sqlite_exec.
После того, как каждая строка ввода получена, sqlite вызывает
sqlite_complete на всем вводе в его буфере.
Если sqlite_complete = true, вызывается sqlite_exec
и входной буфер перезагружается. Если sqlite_complete вернет false,
другая строка текста прочитана и добавлена к входному буферу. Библиотека SQLite экспортирует строковую константу, названную
sqlite_version, которая содержит номер версии библиотеки.
Заголовочный файл содержит макро SQLITE_VERSION.
При желании программа может сравнить макрос SQLITE_VERSION с
sqlite_version, чтобы проверить, что номер версии
заголовочного файла и библиотеки соответствуют. По умолчанию SQLite предполагает, что все данные используют
8 битов фиксированного размера (iso8859). Но если вы указали опцию
--enable-utf8 скрипта настройки, тогда библиотека предполагает символы UTF-8
переменной длины. Это имеет значение для операторов LIKE и GLOB, а также
функций LENGTH() и SUBSTR(). Статическая последовательность
sqlite_encoding будет установлена в "UTF-8" или "iso8859",
чтобы указать, как библиотека была собрана. Кроме того, заголовочный файл
sqlite.h файл определит один из макросов
SQLITE_UTF8 или SQLITE_ISO8859. Обратите внимание на то, что механизм кодировки символов, используемый
SQLite, не может быть изменен во времени выполнения.
Это только выбор времени компиляции. Символьная строка sqlite_encoding
просто говорит вам, как библиотека была собрана. Процедура sqlite_busy_handler может использоваться, чтобы
зарегистрировать занятый отзыв в открытой базе данных SQLite. Занятый отзыв
будет вызван каждый раз, когда SQLite пытается получить доступ к базе данных,
которая блокирована. Отзыв будет, как правило, делать некоторую другую
полезную работу или возможно спать, чтобы дать блокировке шанс очиститься.
Если возврат отзыва отличен от нуля, то SQLite попробует еще раз получить
доступ к базе данных и повторит цикл.
Если отзыв возвращает ноль, то SQLite прерывает текущую операцию и
возвращает SQLITE_BUSY. Параметры sqlite_busy_handler это
непрозрачная структура, возвращенная из sqlite_open,
указатель на занятую функцию обратного вызова и универсальный указатель,
который будет передан как первый аргумент занятому отзыву.
Когда SQLite вызывает занятый отзыв, он посылает ему три аргумента:
универсальный указатель, который был передан как третий аргумент
sqlite_busy_handler, название таблицы базы данных или индекса, к
которому библиотека пытается получить доступ, и число раз, которое библиотека
попыталась получить доступ к таблице базы данных или индексу. Для общего случая, где мы хотим, чтобы занятый отзыв спал, библиотека
SQLite обеспечивает функцию sqlite_busy_timeout. Первый аргумент
sqlite_busy_timeout это указатель на открытую базу данных SQLite,
второй аргумент число миллисекунд. После того, как sqlite_busy_timeout
выполнен, библиотека SQLite будет ждать снятия блокировки
по крайней мере заданное количество миллисекунд, прежде чем это возвратит
SQLITE_BUSY. Определение нуля миллисекунд для тайм-аута восстанавливает
поведение по умолчанию. Есть четыре сервисных функции: Реализует ту же самую функциональность запроса как sqlite_exec и
sqlite_get_table. Но вместо того, чтобы брать полный SQL-оператор в
качестве второго аргумента, _printf
берет строку формата printf-стиля. SQL-оператор, который будет выполнен,
произведен от этой строки формата и от любых дополнительных аргументов
до конца вызова функции. Есть два преимущества для использования функции SQLite printf вместо
sprintf. В первую очередь, с SQLite printf
никогда нет опасности переполнить статический буфер, как с sprintf.
SQLite printf автоматически ассигнуют (и позже освобождает), столько памяти,
как необходимо, чтобы считать SQL-операторы произведенными. Второе преимущество, которое SQLite printf имеют перед
sprintf, является двумя новыми параметрами форматирования, специально
предназначенными, чтобы поддержать строковые литералы в SQL. В строке формата
%q параметр форматирования работает как %s, в который это читает законченную
пустым указателем последовательность из списка аргументов и вставляет ее в
результат. Но %q переводит вставленную последовательность, делая две копии
каждой одинарной кавычки (') в последовательности, которой заменяют.
Это имеет эффект возможности избежать значения конца последовательности
одинарной кавычки в строковом литерале. %Q работает похоже: это переводит
одинарные кавычки как %q и дополнительно экранирует получившую строку
одинарными кавычками. Если аргумент параметров форматирования %Q это
указатель NULL, получившаяся строка это NULL без одинарных кавычек. Рассмотрите пример. Предположим, что вы пытаетесь вставить значение
последовательности в таблицу базы данных, где значение
последовательности было получено из ввода данных пользователем.
Предположим, что последовательность, которая будет вставлена, сохранена в
переменной, названной zString. Код, чтобы сделать вставку,
мог бы быть похожим на это: Если zString хранит текст, например, "Hello", то это будет работать просто
великолепно. Но предположите, что пользователь вводит в последовательность
"Hi y'all!". Произведенный SQL-оператор читает следующим образом:
Это не действительный SQL из-за апострофа в слове "y'all".
Но если %q параметр форматирования используется вместо %s: Тогда произведенный SQL будет похож на следующее: Здесь апостроф экранирован, и SQL-оператор правильно построен.
Производя SQL на лету от данных, которые могли бы содержать символ
одинарной кавычки ('), всегда хорошая идея использовать SQLite printf
и параметр форматирования %q вместо sprintf. Если параметр форматирования %Q используется вместо %q, как это: Тогда произведенный SQL будет похож на следующее: Если zString = NULL, произведенный SQL будет похож на следующее: Все _printf() выше строятся вокруг следующих двух функций: sqlite_mprintf() работает как стандартная библиотека
sprintf() за исключением того, что это пишет свои результаты
в память, полученную от malloc(), и возвращает указатель на буфер.
sqlite_mprintf() также понимает расширения %q и %Q, описанные выше.
sqlite_vmprintf() является varargs-версией того же самого.
Указатель строки должен быть освобожден, передав его
sqlite_freemem(). sqlite_progress_handler() может использоваться, чтобы
зарегистрировать код отзыва в базе данных SQLite, который будет вызываться
периодически во время длительных sqlite_exec(), sqlite_step()
и различных функций обертки. Отзыв вызван каждые N действий виртуальной машины, где N поставляется как
второй аргумент sqlite_progress_handler().
Третий и четвертый аргументы sqlite_progress_handler()
являются указателем на код, который будет вызван, и пустой указатель,
который будет передан ему как первый аргумент. Время, потраченное, чтобы выполнить каждую эксплуатацию виртуальной
машины, может измениться на основе многих факторов. Типичная стоимость для PC
на 1 ГГц между половиной и третью миллиона в секунду, но может быть намного
выше или понизиться, в зависимости от запроса. Трудно наметить фоновые
работы на основе операций по виртуальной машине.
Вместо этого рекомендуется, чтобы отзыв намечался относительно часто (скажем,
каждые 1000 инструкций), и внешний код
таймера раньше определял, нужно ли фоновыми заданиями управлять. Начиная с версии 2.4.0, SQLite позволяет языку SQL быть расширенным с
новыми функциями, осуществленными как C-код.
Следующий интерфейс используется: Интерфейс sqlite_create_function()
используется, чтобы создать регулярные функции, а
sqlite_create_aggregate() используется, чтобы создать новые агрегатные
функции. В обоих случаях db это
открытая база данных SQLite, на которой должны быть зарегистрированы функции,
zName название новой функции, nArg количество аргументов и
pUserData указатель, через который передают данные функции.
Обе функции возвращают 0 при успехе и отличное от нуля значние, если есть
какие-либо ошибки. Длина имени функции не может превысить 255 знаков. Любая попытка создать
функцию, имя которой превышает 255 знаков в длину, приведет к ошибке. Для регулярных функций отзыв xFunc
вызван однажды для каждого вызова функции. Внедрение xFunc должно вызвать
один из интерфейсов sqlite_set_result_..., чтобы возвратить его
результат. sqlite_user_data() может использоваться, чтобы получить
указатель pUserData, который был передан, когда
функция была зарегистрирована. Для агрегатных функций отзыв xStep вызван
для каждой строки в результате и затем вызывается xFinalize
в конце, чтобы вычислить окончательный ответ. xStep может использовать
интерфейс sqlite_aggregate_context(), чтобы ассигновать память,
которая будет уникальна для того конкретного случая функции SQL. Эта память
будет автоматически удалена после того, как вызовут xFinalize.
sqlite_aggregate_count() может использоваться, чтобы узнать, сколько
строк данных было передано к совокупности. xFinalize должен вызвать один из
интерфейсов sqlite_set_result_..., чтобы установить
конечный результат совокупности. SQLite теперь осуществляет все свои встроенные функции, используя этот
интерфейс. Для получения дополнительной информации и примеров о том, как
создать новые функции SQL, рассмотрите исходный код SQLite в
файле func.c. Если SQLite собран с макросом препроцессора THREADSAFE = 1,
то безопасно использовать SQLite от двух или больше потоков
того же самого процесса в то же время. Но у каждого потока
должен быть свой собственный указатель sqlite*, возвращенный
sqlite_open. Для двух или больше потоков
никогда не безопасно получить доступ к тому же самому указателю
sqlite* в то же время. В предварительно собранных библиотеках SQLite, доступных на веб-сайте,
версии Unix собраны с выключенным THREADSAFE, но версии Windows собраны с
включенным THREADSAFE. Если вам нужно что-то другое, это необходимо
будет повторно собрать. В Unix указатель sqlite* нельзя передать через
системный вызов fork()
в дочерний процесс. Дочерний процесс должен открыть свою собственную
копию базы данных после fork(). Для примеров того, как интерфейс C/C++ SQLite может использоваться,
обратитесь к исходному коду для программы sqlite в файле
src/shell.c дерева
исходных текстов. Дополнительная информация о sqlite доступна в
cli.html.
См. также источники к интерфейсу Tcl для SQLite в исходном файле
src/tclsqlite.c.
Choose any three.Интерфейс языка C SQLite Version 2
1.0. Ядро API
typedef struct sqlite sqlite;
#define SQLITE_OK 0 /* Successful result */
sqlite *sqlite_open(const char *dbname, int mode, char **errmsg);
void sqlite_close(sqlite *db);
int sqlite_exec(sqlite *db, char *sql,
int (*xCallback)(void*,int,char**,char**),
void *pArg, char **errmsg
);
1.1. Открытие базы данных
1.2. Закрытие базы данных
1.3. Выполнение SQL-операторов
int Callback(void *pArg, int argc, char **argv, char **columnNames)
{
return 0;
}
argv[i][0] == 0
argv[i] == 0
Второй параметр (argc) и четвертый параметр (columnNames) все еще
действительны и могут использоваться, чтобы определить число и названия
столбцов результата, если был результат. Поведение по умолчанию не должно
вызывать отзыв вообще, если набор результатов пуст.
argv == 0
1.4. Коды ошибок
#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 constraint 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.0. Доступ к данным без использования функции обратного вызова
typedef struct sqlite_vm sqlite_vm;
int sqlite_compile(
sqlite *db, /* The open database */
const char *zSql, /* SQL statement to be compiled */
const char **pzTail, /* OUT: uncompiled tail of zSql */
sqlite_vm **ppVm, /* OUT: the virtual machine to execute zSql */
char **pzErrmsg /* OUT: Error message. */
);
int sqlite_step(
sqlite_vm *pVm, /* The virtual machine to execute */
int *pN, /* OUT: Number of columns in result */
const char ***pazValue, /* OUT: Column data */
const char ***pazColName /* OUT: Column names and datatypes */
);
int sqlite_finalize(
sqlite_vm *pVm, /* The virtual machine to be finalized */
char **pzErrMsg /* OUT: Error message */
);
2.1. Компилирование SQL-оператора в виртуальную машину
2.2. Постепенное выполнение SQL-оператора
2.3. Удаление виртуальной машины
3.0. Extended API
int sqlite_last_insert_rowid(sqlite*);
int sqlite_changes(sqlite*);
int sqlite_get_table(sqlite*, char *sql, char ***result, int *nrow,
int *ncolumn, char **errmsg);
void sqlite_free_table(char**);
void sqlite_interrupt(sqlite*);
int sqlite_complete(const char *sql);
void sqlite_busy_handler(sqlite*, int (*)(void*,const char*,int), void*);
void sqlite_busy_timeout(sqlite*, int ms);
const char sqlite_version[];
const char sqlite_encoding[];
int sqlite_exec_printf(sqlite*, char *sql, int (*)(void*,int,char**,char**),
void*, char **errmsg, ...);
int sqlite_exec_vprintf(sqlite*, char *sql, int (*)(void*,int,char**,char**),
void*, char **errmsg, va_list);
int sqlite_get_table_printf(sqlite*, char *sql, char ***result,
int *nrow, int *ncolumn, char **errmsg, ...);
int sqlite_get_table_vprintf(sqlite*, char *sql, char ***result, int *nrow,
int *ncolumn, char **errmsg, va_list);
char *sqlite_mprintf(const char *zFormat, ...);
char *sqlite_vmprintf(const char *zFormat, va_list);
void sqlite_freemem(char*);
void sqlite_progress_handler(sqlite*, int, int (*)(void*), void*);
3.1. ROWID новой вставки
3.2. Количество строк, которые изменились
3.3. Запрос памяти, полученной из malloc()
SELECT employee_name, login, host FROM users WHERE login LIKE 'd%';
nrow = 2
ncolumn = 3
result[0] = "employee_name"
result[1] = "login"
result[2] = "host"
result[3] = "dummy"
result[4] = "No such user"
result[5] = 0
result[6] = "D. Richard Hipp"
result[7] = "drh"
result[8] = "zadok"
SELECT employee_name, login, host FROM users WHERE employee_name IS NULL;
nrow = 0
ncolumn = 0
result = 0
nrow = 0
ncolumn = 3
result[0] = "employee_name"
result[1] = "login"
result[2] = "host"
3.4. Прерывание операции SQLite
3.5. Тестирование на полный SQL-оператор
3.6. Строка версии библиотеки
3.7. Кодировка символов библиотеки
3.8. Изменение ответа библиотеки на блокировку файлов
3.9. Использование функции обертки _printf()
sqlite_exec_printf(db, "INSERT INTO table1 VALUES('%s')",
0, 0, 0, zString);
INSERT INTO table1 VALUES('Hi y'all')
sqlite_exec_printf(db, "INSERT INTO table1 VALUES('%q')",
0, 0, 0, zString);
INSERT INTO table1 VALUES('Hi y''all')
sqlite_exec_printf(db, "INSERT INTO table1 VALUES(%Q)",
0, 0, 0, zString);
INSERT INTO table1 VALUES('Hi y''all')
INSERT INTO table1 VALUES(NULL)
char *sqlite_mprintf(const char *zFormat, ...);
char *sqlite_vmprintf(const char *zFormat, va_list);
3.10. Выполнение фоновых заданий во время выполнения больших запросов
4.0. Добавление новых функций SQL
typedef struct sqlite_func sqlite_func;
int sqlite_create_function(sqlite *db, const char *zName, int nArg,
void (*xFunc)(sqlite_func*,int,const char**),
void *pUserData);
int sqlite_create_aggregate(sqlite *db, const char *zName, int nArg,
void (*xStep)(sqlite_func*,int,const char**),
void (*xFinalize)(sqlite_func*),
void *pUserData);
char *sqlite_set_result_string(sqlite_func*,const char*,int);
void sqlite_set_result_int(sqlite_func*,int);
void sqlite_set_result_double(sqlite_func*,double);
void sqlite_set_result_error(sqlite_func*,const char*,int);
void *sqlite_user_data(sqlite_func*);
void *sqlite_aggregate_context(sqlite_func*, int nBytes);
int sqlite_aggregate_count(sqlite_func*);
5.0. Мультипоточность и SQLite
6.0. Примеры использования