Страница 1 из 3

Класс-обёртка для SQLite

СообщениеДобавлено: 03.06.2010 11:08:36
Nik
По ходу переноса одного из своих проектов в Lazarus скопилировал (собственно, даже без изменений) класс-обёртку для SQLite. Когда-то нашёл этот класс в Сети и немного подправил удобства ради.
Имхо, такой подход удобнее стандартного компонента из LCL (хотя это дело вкуса :) ). Исходный класс был вполне себе кроссплатформенным (подозреваю, что его уже когда-то адаптировали под FPC), но сейчас ничего не обещаю (вроде ничего принципиально не менял, но всё-таки).

В общем, если вдруг кому пригодится - пользуйтесь :) Простенький пример - в комплекте.

Re: Класс-обёртка для SQLite

СообщениеДобавлено: 12.06.2010 16:21:14
modjo
Не подскажите как подцепится к существующей базе? Если делать

DBase := TSQLiteDataBase.Create('test.db');

База будет переписана.

Документации, думаю, нет?

Re: Класс-обёртка для SQLite

СообщениеДобавлено: 12.06.2010 17:26:06
Odyssey
modjo писал(а):Не подскажите как подцепится к существующей базе?

Код: Выделить всё
TSQLiteDataBase.Create('существующая база.db')

Убедитесь, что строка с имем файла в UTF-8.
modjo писал(а):Если делать
DBase := TSQLiteDataBase.Create('test.db');
База будет переписана.

Не верю! :) В версии для Delphi не переписывалась, а реализация TSQLiteDataBase.Create с тех пор не поменялась. Неужели действительно переписывается?
modjo писал(а):Документации, думаю, нет?

Я не видел. Но исходники небольшие и весьма читабельные, плюс есть пример.

Re: Класс-обёртка для SQLite

СообщениеДобавлено: 12.06.2010 17:32:47
modjo
Увы, переписывает.

Re: Класс-обёртка для SQLite

СообщениеДобавлено: 12.06.2010 17:54:00
Odyssey
Только что попробовал пример из комплекта. Не переписывает.
После TSQLiteDatabase.Create(BD_file); все таблицы на месте, записи тоже.

Re: Класс-обёртка для SQLite

СообщениеДобавлено: 12.06.2010 20:17:09
modjo
Вот мой код:

Код: Выделить всё
SQL_db := TSQLiteDatabase.Create(PatchDB.Text);
      showmessage('test');
      // Добавляем таблицы.
      for i := 0 to SoftList.Items.Count - 1 do
        begin
          // Таблица cодержит только данные пользователя. Обязательна к созданию.
          SQL_db.ExecSQL('CREATE TABLE IF NOT EXISTS [users] ([id] INTEGER PRIMARY KEY, [username] CHAR, [org] CHAR, [position] CHAR, [ncomp] CHAR, [compname] CHAR, [ipcomp] CHAR)');
          // В этой таблице хранится чисто техническая информация для программы.
          SQL_db.ExecSQL('CREATE TABLE IF NOT EXISTS [forprog] ([lastid] INTEGER)');
          // Radmin.
          if (SoftList.Checked[i] = True) and (SoftList.Items.Strings[i] = 'RAdmin') then
            SQL_db.ExecSQL('CREATE TABLE IF NOT EXISTS [radmin] ([id] INTEGER PRIMARY KEY, [org] CHAR, [sn] CHAR, [number] INTEGER)');
          // TheBat!
          if (SoftList.Checked[i] = True) and (SoftList.Items.Strings[i] = 'The Bat!') then
            SQL_db.ExecSQL('CREATE TABLE IF NOT EXISTS [thebat] ([id] INTEGER PRIMARY KEY, [org] CHAR, [sn] CHAR, [number] INTEGER)');
          // Lingvo.
          if (SoftList.Checked[i] = True) and (SoftList.Items.Strings[i] = 'Lingvo') then
            SQL_db.ExecSQL('CREATE TABLE IF NOT EXISTS [lingvo] ([id] INTEGER PRIMARY KEY, [org] CHAR, [sn] CHAR)');
          // NOD32.
          if (SoftList.Checked[i] = True) and (SoftList.Items.Strings[i] = 'NOD32') then
            SQL_db.ExecSQL('CREATE TABLE IF NOT EXISTS [nod32] ([id] INTEGER PRIMARY KEY, [org] CHAR, [sn] CHAR)');
        end;

      // Очищаем память.
        SQL_db.Free
;

создаю в начале базу. Не выходя из программы создаю базу заново, но указываю теперь другой чекбокс. И пока мне показывает сообщение (showmessage('test');) я вижу что файл изменился. смотрю базу через sqlite datdbase browser - пустая...

Добавлено спустя 7 минут 28 секунд:
И кстати. Программа, что идет с исходниками тож переписывает свою базу example.db3. Обратите внимание на время изменения файла, каждый разменяется.

Re: Класс-обёртка для SQLite

СообщениеДобавлено: 12.06.2010 21:55:24
Nik
База заново создаваться не должна. Функция Create создаёт только линк. Файл при запуске примера будет изменяться - смотрите внимательно код, там добавляются новые случайные записи при каждом запуске (на событии OnCreate формы).

Re: Класс-обёртка для SQLite

СообщениеДобавлено: 12.06.2010 21:57:22
modjo
создал форму с одной кнопкой и кодом

Код: Выделить всё
  sql := tsqlitedatabase.Create('test.db');
  sql.Free;


+ в отдельной софтине создал базу ну и попробовал. Не переписывает. Почему тогда в моём коде переписывает? Не понятно, буду завтра разбираться...

Re: Класс-обёртка для SQLite

СообщениеДобавлено: 12.06.2010 21:58:25
Nik
смотрю базу через sqlite datdbase browser - пустая...

Смотрите до закрытия вашей программы? У SQLite своеобразная система транзакций, если не подтверждать запись в БД функцией Commit, то файл может не изменяться вплоть до закрытия БД. Хотя с этим я особо не разбирался - в реальной работе никаких проблем не возникает.


PS. Выложенный класс я использую в реальной проге, портированной недавно из Delphi - всё работает без проблем (уж база точно не переписывается).

Re: Класс-обёртка для SQLite

СообщениеДобавлено: 12.06.2010 22:00:45
modjo
Nik
Код я видел. Просто в моем коде что-то не то, только понять не могу что. Вроде всё просто, а таблица трётся, за место неё другая, которая отмечена чекбоксом. Завтра уже буду разбираться...

Re: Класс-обёртка для SQLite

СообщениеДобавлено: 12.06.2010 22:49:42
Odyssey
modjo
Можно попробовать после успешного создания установить файлу БД через файл-менеджер атрибут ReadOnly, потом запустить программу ещё раз и посмотреть где она упадёт.

Nik
Есть пара предложений по библиотеке:
1) SQLiteTable3.pas, строка 120, используется тип TDate. В текущем релизе FPC 2.4.0 этот тип не определён в модуле System. Он есть только в trunk/2.5.x. В результате на релизном FPC модуль не компилируется. Есть предложение изменить его на TDateTime, или объявить type TDate = type TDateTime, как сделали в Lazarus.
2) Там же, строка 173. UTF8String -- это тот же string, поэтому приведение типов в данном случае не даёт никакого результата. Есть предложение убрать приведение и временную переменную, чтобы не вводили в заблуждение.

Re: Класс-обёртка для SQLite

СообщениеДобавлено: 13.06.2010 00:00:48
Nik
Odyssey писал(а):modjo
Есть пара предложений по библиотеке:
1) SQLiteTable3.pas, строка 120, используется тип TDate. В текущем релизе FPC 2.4.0 этот тип не определён в модуле System. Он есть только в trunk/2.5.x. В результате на релизном FPC модуль не компилируется. Есть предложение изменить его на TDateTime, или объявить type TDate = type TDateTime, как сделали в Lazarus.
2) Там же, строка 173. UTF8String -- это тот же string, поэтому приведение типов в данном случае не даёт никакого результата. Есть предложение убрать приведение и временную переменную, чтобы не вводили в заблуждение.

Собственно, всё это - остатки от портирования из Delphi (исходный класс дописывал/менял ещё для D7). Хотя насчёт TDate странно - я компилировал в последнем Daily Snapshots (там FPC 2.4.2). Не знаю, есть ли смысл подстраиваться под версию, которая скоро уйдёт в прошлое :)
А преобразование UTF8String заменю, ага. В изначально юникодном Lazarus оно не имеет смысла, в отличие от старых версий Delphi.

Добавлено спустя 4 минуты 27 секунд:
Обновил вложение - убрал лишнее преобразование UTF8String/string.

Re: Класс-обёртка для SQLite

СообщениеДобавлено: 13.06.2010 06:57:45
modjo
Блин. Я совсем забыл про

Код: Выделить всё
if NOT DeleteFile(PatchDB.Text) then


Сорри, за свой склероз...

Re: Класс-обёртка для SQLite

СообщениеДобавлено: 13.06.2010 13:27:50
Nik
Бывает :) Иной раз полночи ищешь багу - вроде всё верно, а не работает. Утром на свежую голову замечаешь какой-нибудь лишний not или случайно закомментированную строчку :)

Re: Класс-обёртка для SQLite

СообщениеДобавлено: 26.07.2010 12:51:17
modjo
Не подскажите возможно ли обновить ячейку не считывая заранее значения? Что-то типа этого:

update users set username=username+" егоров" where uid="1"