Нативная внешняя компонента для 1С 8 для работы с базами данных sqlite. Позволяет выполнять запросы к базам данных sqlite и получать их результаты в виде ТаблицыЗначений или массива массивов.
Поддерживает работу в:
- Windows x86
- Windows x64
- Linux x64
Сама библиотека sqlite подключена статически, то есть внедрена в ВК. Используется версия 3.46.1. Версию sqlite можно узнать запросом
select sqlite_version()
Базы данных sqlite хранят текст в одной кодировке, выбираемой при создании базы данных - UTF-8 либо UTF-16.
Несмотря на то, что работать возможно с базами с любой кодировкой, стоит учитывать, что внутри 1С для данных
типа "Строка" используется кодировка UTF-16, поэтому при чтении текста из баз с этой кодировкой движку sqlite
не нужно выполнять каждый раз перекодировку текста из UTF-8 в UTF-16 и наоборот.
Поэтому из соображений производительности, если вы планируете пользоваться базой данных в-основном в 1С,
создавайте её в кодировке UTF-16. Для этого после первого открытия базы данных выполните pragma encoding
:
// Создать пустую базу в файле
ИмяФайла = ПолучитьИмяВременногоФайла("db");
база.ОткрытьБазуДанных(ИмяФайла);
база.Выполнить("pragma encoding='UTF-16'");
В компоненте к движку sqlite добавлена минимальная поддержка регистронезависимости Unicode-символов, для работы функций upper
, lower
,
fold
, title
, unaccent
, like
и collate nocase
. Правильно обрабатываются символы только из первой плоскости Unicode (до 0xFFFF).
Кроме того, преобразование регистра выполняется только "один символ - в один символ", т.е. некоторые случаи, при которых один символ
может в другом регистре стать двумя символами и наоборот - не учитываются. Для регистронезависимого сравнения используется fold
.
Собирается как cmake проект в Visual Studio Community Edition 2022. Под windows проверял в MSVC и Clang. Под linux собирается подключением к удалённой машине с установленным Clang, собирал на clang-16. В бинарной сборке:
- win x86 собрана MSVC
- win x64 - clang-cl 16
- Linux x64 - clang-16, в двух версиях, под Ubuntu 18.04 с GLIBC 2.25, под Ubuntu 22 - с GLIBC 2.34
Подключается как обычная нативная ВК, например так
Функция ПодключитьВК()
ПутьКВК = КаталогПрограммы();
СистемнаяИнформация = Новый СистемнаяИнформация;
Если СистемнаяИнформация.ТипПлатформы = ТипПлатформы.Windows_x86 или СистемнаяИнформация.ТипПлатформы = ТипПлатформы.Windows_x86_64 Тогда
ПутьКВК = ПутьКВК + "v8sqlite.dll";
ИначеЕсли СистемнаяИнформация.ТипПлатформы = ТипПлатформы.Linux_x86_64 Тогда
ПутьКВК = ПутьКВК + "libv8sqlite.so";
КонецЕсли;
Если не ПодключитьВнешнююКомпоненту(ПутьКВК, "v8sqlite", ТипВнешнейКомпоненты.Native) Тогда
Предупреждение("Не удалось подключить внешнюю компоненту " + ПутьКВК);
Возврат Ложь;
КонецЕсли;
Возврат Истина;
КонецФункции // ПодключитьВК()
После подключения доступен к созданию объект внешней компоненты, через который и можно будет работать с базой даных sqlite.
база = Новый("AddIn.v8sqlite.v8sqlite");
Строка, только чтение. Версия компоненты.
Булево, чтение/запись. По умолчанию Ложь.
Флаг, нужно ли при возникновении исключения добавлять текстовое описание ошибки штатным для ВК методом AddError
.
Дело в том, что вывод такого сообщения в окно сообщений невозможно подавить. Даже если вы отловили исключение с помощью
Попытка Исключение
и программа продолжает работу - в окно сообщений всё-равно выдаст текст ошибки.
Если значение свойства Ложь
, то текст ошибки не будет выдавать в исключении (будет просто штатное "Ошибка при вызове метода объекта"),
которое не выдает сообщение в случае отлова попыткой. Описание ошибки в этом случае можно прочитать в свойстве ОписаниеОшибки
.
Строка. Только чтение.
Содержит текстовое описание последней ошибки. Ошибка может быть как возвращенная sqlite базой, так и самой компоненты.
Попытка
база.Выполнить("create table test(a,b,c");
Исключение
Сообщить(база.ОписаниеОшибки);
КонецПопытки;
Булево. Только чтение.
Показывает, открыта ли в данный момент база данных.
Число. Только чтение.
После выполнения операций вставки выдает ID последней вставленной строки.
Число. Только чтение.
Показывает, сколько строк было вставлено/изменено во время выполнения последнего запроса.
Открывает базу данных. Если была открыта база данных, она закрывается. Если файла с заданным именем не существует, будет создана новая пустая база данных.
Параметры:
- ИмяФайла: Строка, обязательный. Имя открываемого файла. Специальное имя
":memory:"
открывает базу данных в памяти. Поддерживается имена в URI формате, позволяющие задавать дополнительные параметры отрытия файла.
Возвращаемое значение - нет. При ошибке выбрасывает исключение.
Пример:
база = Новый("AddIn.v8sqlite.v8sqlite");
// Открыть базу в памяти
база.ОткрытьБазуДанных(":memory:");
...
// Создать пустую базу в файле
ИмяФайла = ПолучитьИмяВременногоФайла("db");
база.ОткрытьБазуДанных(ИмяФайла);
Закрывает открытую базу данных, если она была ранее открыта. Параметров нет. Возвращаемого значения нет.
Выполняет переданный текст запроса с помощью sqlite3_exec
.
Служит в основном для выполнения запросов insert/update/delete, то есть не возвращающих результата.
Можно указывать текст нескольких запросов, разделяя их ;
.
Пример:
база = Новый("AddIn.v8sqlite.v8sqlite");
база.ОткрытьБазуДанных(":memory:");
база.Выполнить("
|create table test(a,b,c);
|insert into test values
|(1, 2.3, null),
|('text', x'414243', datetime('now'))
|");
Возвращаемого значения нет.
Подготавливает запрос для дальнейшего неоднократного выполнения.
Параметры:
- ИмяЗапроса - Строка, обязательный. Любое уникальное в пределах этой базы имя для дальнейшего обращения к запросу. Если запрос с таким именем уже был подготовлен ранее, он будет заменён.
- Текст запроса - Строка, обязательный. Текст sql-запроса.
Возвращаемого значения нет. При ошибке в тексте запроса - выкинет исключение.
Пример:
база = Новый("AddIn.v8sqlite.v8sqlite");
база.ОткрытьБазуДанных(":memory:");
база.ПодготовитьЗапрос("Запрос1", "
|select * from test where a = @p1
|");
УстановитьПараметр(ИмяЗапроса, ИмяПараметра, ЗначениеПараметра) / BindParam(QueryName, ParamName, ParamValue)
Устанавливает значение sql-параметра для ранее подготовленного запроса.
Параметры:
- ИмяЗапроса - Строка, обязательный. Имя, которое использовалоь в методе
ПодготовитьЗапрос
. Задаёт, для какого запроса устанавливается параметр. - ИмяПараметра - Строка или Число. Задает, какой параметр устанавливается. Передаётся либо имя параметра, либо его номер.
Нумерация параметров с
1
. - ЗначениеПараметра - Число, Строка, ДвоичныеДанные, Дата, Неопределено, Null, Булево. Необязательный.
При отсутствии, Неопределено или Null - устанавливает null.
Дата конвертируется в формат
YYYY-MM-DD HH:MM:SS
- так, как возвращает функция sqlitedatetime
. Булево преобразуется в 0 или 1.
Возвращаемого значения нет.
Пример:
база = Новый("AddIn.v8sqlite.v8sqlite");
база.ОткрытьБазуДанных(":memory:");
база.ПодготовитьЗапрос("Запрос1", "
|select * from test where a = @p1
|");
...
база.УстановитьПараметр("Запрос1", "@p1", 1);
ВыполнитьЗапрос(Запрос, ФорматОтвета, [КолонкиСДатой]) / ExecQuery(Query, AnswerFormat, [DateColumns])
Выполняет запрос с выдачей результата.
Параметры:
- Запрос - Строка, обязательный. Здесь можно либо указать имя ранее подготовленного запроса, либо просто текст запроса. В этом случае запрос подготавливается, выполняется и закрывается. В случае подготовленного запроса он выполняется с учётом установленных параметров, после все установленные параметры сбрасываются.
- ФорматОтвета - Строка, обязательный. Задаёт, в каком формате будет выдаваться результат выполнения запроса. Может принимать значения "JSON" или "ТаблицаЗначений" / "ValueTable". Регистронезависимый.
- КолонкиСДатой - Строка, необязательный. Перечисленные через запятую названия или номера колонок, значения
в которых нужно преобразовать в Дату. Нумерация колонок с нуля. Чтобы преобразование сработало, реальное
значение должно быть строкой длиной 19 символов, т.е. датой в формате "YYYY-MM-DD HH:MM:SS", так, как выдаёт
функция sqlite
datetime
. Компонента не парсит дату, а просто берёт куски из этой строки и расставляет в нужном 1С формате.
Возвращаемое значение: строка, если выполняется запрос select
.
Для остальных видов запросов - пустое значение.
При возникновении sql-ошибки - выкидывает исключение.
Возвращаемая строка зависит от указанного при вызове метода формате.
Для формата "ТаблицаЗначений" - выдаётся строка, которая методом ЗначениеИзСтрокиВнутр
преобразуется
в Таблицу значений. Названия колонок запроса становятся именем и заголовком колонок таблицы значений.
Для формата "JSON" возвращается строка, которая через XDTO преобразуется в массив. Элементы массива - тоже массивы, строки результата запроса. Самой первой строкой идёт массив с названиями колонок.
Преобразование типов sqlite:
integer
,real
- преобразуются в тип 1СЧисло
.text
- в типСтрока
.null
- вNull
.blob
- вДвоичныеДанные
.
Если для колонки задано преобразование в Дату, компонента попытается это сделать,
см. описание параметра КолонкиСДатой
.
Пример:
// Получение как ТЗ
тз = ЗначениеИзСтрокиВнутр(база.ВыполнитьЗапрос("
|select a, b, c as dt
|from test where a = 100
|", "ТаблицаЗначений", "dt"));
// Получение как массива массивов
Функция JSONВМассив(текст)
ч = Новый ЧтениеJSON;
ч.УстановитьСтроку(текст);
Возврат СериализаторXDTO.ПрочитатьJSON(ч);
КонецФункции
...
результат = JSONВМассив(база.ВыполнитьЗапрос("
|select a [col a], b, c as dt
|from test
|", "json", "dt"));
Закрывает ранее подготовленный запрос и удаляет его из списка запросов. При закрытии базы все подготовленные запросы удаляются автоматически.
Параметры:
- ИмяЗапроса - строка, обязательный. Имя запроса, использованное ранее в методе
ПодготовитьЗапрос
.
Возвращаемого значения нет.
Пример:
база.УдалитьЗапрос("Запрос1");