Для тех, кто случайно наткнулся на эту статью. Я хочу провести эксперимент с продвижением в социальной сети VK.com, используя автоматизацию. Для этого я пишу (пусть и очень медленно, в свободное время) свое приложение и частично освещаю ход работ на этом блоге.
В предыдущей серии я рассказала про компонент для браузера, который буду использовать. Настало время определиться с данными.
Сначала хотела вообще обойтись без БД, а заодним и описать работу с XML, но, подумав, решила, что без базы будет сложно (и неудобно, если пользователей заведется много). Особенно, если разрабатывать с перспективами. Поэтому сегодня речь пойдет о SQLite.
Чем руководствовалась при выборе БД?
- Максимальная простота и легкость.
- Минимум телодвижений для работы приложения на другой машине: надо просто скопировать все содержимое папки к себе (кроме файлов БД нужна только dll).
Библиотека DISQLite для работы с SQLite в Delphi 7
Их существует несколько. Например, я встречала упоминания о DISQLite, ASQLite, ZeosDBO. Я пробовала только первую, поэтому про нее сейчас и расскажу. Если кто-нибудь использовал другие, поделитесь, пожалуйста, впечатлениями в комментариях.
Установка DISQLite
Скачиваем файлы библиотеки. Подробно процесс установки описан в хэлпе, который прилагается к либе, поэтому переводить и размещать его здесь не имеет смысла. В принципе, вся установка может быть сведена к добавлению библиотек в Tools — Environment Options — Library. Но я устанавливала еще и компоненты. После установки пакета DISQLite3_D7.dpk появляется вкладка Yunga с тремя компонентами:
Создание базы данных
Прикинем, что нам надо хранить в базе данных. Пока по-минимуму.
Во-первых, таблица с юзерами.
Во-вторых, таблица с задачами (постинг картинок, текстов и т.д.).
В-третьих, таблица для хранения данных о приглашенных в друзья. Чтобы не повторяться и не приглашать повторно одних и тех же. Через некоторое время, если юзера взаимно не зафрендили, отписываться от него и позже уже не приглашать.
Все это только наброски, я еще сама точно не знаю, чем потом дополню базу.
Я покажу, как можно открыть базу (или создать, если такой базы нет) из приложения. Как вариант, можно создать ее в каком-нибудь менеджере БД (мне нравится бесплатная программа SQLite Expert Personal, ее функционала вполне достаточно), а дальше работать с созданной базой через IDE-компоненты.
Вот как выглядит окно SQLite Expert Personal с открытой БД:
Итак, код создания базы данных SQLite с помощью DISQLite в Delphi7:
Во-первых, таблица с юзерами.
Во-вторых, таблица с задачами (постинг картинок, текстов и т.д.).
В-третьих, таблица для хранения данных о приглашенных в друзья. Чтобы не повторяться и не приглашать повторно одних и тех же. Через некоторое время, если юзера взаимно не зафрендили, отписываться от него и позже уже не приглашать.
Все это только наброски, я еще сама точно не знаю, чем потом дополню базу.
Я покажу, как можно открыть базу (или создать, если такой базы нет) из приложения. Как вариант, можно создать ее в каком-нибудь менеджере БД (мне нравится бесплатная программа SQLite Expert Personal, ее функционала вполне достаточно), а дальше работать с созданной базой через IDE-компоненты.
Вот как выглядит окно SQLite Expert Personal с открытой БД:
Итак, код создания базы данных SQLite с помощью DISQLite в Delphi7:
var
vkBase : TDISQLite3Database;
procedure TfrmMain.FormCreate(Sender: TObject);
var
sSQL : String;
begin
vkBase := TDISQLite3Database.Create(nil);
vkBase.DatabaseName := 'vkBase.db';
try
vkBase.Open; // пытаемся открыть базу, если она не существует — создаем
// если база не существует, будет возвращено EFOpenError
except
on e: EFOpenError do
begin
vkBase.CreateDatabase;
vkBase.Execute('PRAGMA legacy_file_format=OFF;');
end;
end;
try
// создаем все нужные таблицы, если их еще нет
sSQL:='CREATE TABLE if not exists vk_users ( '+
'id INTEGER NOT NULL PRIMARY KEY,'+
'user_name CHAR(50) NOT NULL,'+
'user_email CHAR(20) NOT NULL,'+
'user_pass CHAR(20) NOT NULL,'+
'user_url CHAR(20) NOT NULL,'+
'create_date DATETIME,'+
'dsc TEXT);';
vkBase.Execute(sSQL);
sSQL:='CREATE TABLE if not exists vk_invitations ( '+
'id INTEGER NOT NULL PRIMARY KEY,'+
'user_id INTEGER,'+
'invited_url CHAR(30),'+
'invitation_fd DATETIME,'+
'invitation_td DATETIME,'+
'status SMALLINT NOT NULL DEFAULT 0)';
vkBase.Execute(sSQL);
sSQL:='CREATE TABLE if not exists vk_tasks ( '+
'id INTEGER NOT NULL PRIMARY KEY,'+
'user_id INTEGER,'+
'task_code INTEGER,'+
'task_fd DATETIME,'+
'task_td DATETIME,'+
'image_dir CHAR(50),'+
'text_to_post TEXT,'+
'status SMALLINT NOT NULL DEFAULT 0)';
vkBase.Execute(sSQL);
except
MessageBox(0,'Ошибка при создании таблиц.','Ошибка',MB_OK+MB_ICONERROR);
Application.Terminate;
end;
end;
В FormDestroy не забудьте очистить память, выделенную под vkBase.
Во время написания этого поста столкнулась с одной странной штуковиной, касающейся ключей и автоинкремента.
Сначала следует сказать, что в таблицах SQLite каждая запись снабжается уникальным в рамках этой таблицы ROWID. При добавлении записи этот ключ по умолчанию автоинкрементируется. Чтобы воспользоваться этим механизмом "встроенного инкремента", можно или назвать поле ROWID (еще варианты: _ROWID_, OID), или создать поле типа INTEGER PRIMARY KEY.
Так вот, если в менеджере SQL-код:
Во время написания этого поста столкнулась с одной странной штуковиной, касающейся ключей и автоинкремента.
Сначала следует сказать, что в таблицах SQLite каждая запись снабжается уникальным в рамках этой таблицы ROWID. При добавлении записи этот ключ по умолчанию автоинкрементируется. Чтобы воспользоваться этим механизмом "встроенного инкремента", можно или назвать поле ROWID (еще варианты: _ROWID_, OID), или создать поле типа INTEGER PRIMARY KEY.
Так вот, если в менеджере SQL-код:
CREATE TABLE if not exists vk_users (
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
user_name CHAR(50) NOT NULL,
user_email CHAR(20) NOT NULL,
user_pass CHAR(20) NOT NULL,
user_url CHAR(20) NOT NULL,
create_date DATETIME,
dsc TEXT);
прокатывает, то при открытии такой базы через DISQLite (или при попытке исполнить этот запрос через Execute), выскакивает ошибка SQLite Error 11 - malformed database schema (vk_users) near AUTOINCREMENT. Может, это такой баг (особенность?) DISQLite?
Пожалуй, про создание базы и таблиц — все. Не думаю, что подробно следует освещать выполнение SQL, вроде как проще некуда.
SELECT в DISQLite
Чтобы делать выборку SELECT, в библиотеке есть TDISQLite3UniDirQuery. Небольшой пример, как работать с экземпляром класса безотносительно к конкретно этому приложению. Кто знаком с работой с БД, увидит, что все стандартно, ничего нового и особенного.var
Query : TDISQLite3UniDirQuery;
...
begin
...
Query := TDISQLite3UniDirQuery.Create(nil);
try
Query.Database := vkBase;
Query.SelectSQL := 'select * from vk_users';
Query.Open;
while not Query.EOF do
begin
StringList.Add(Query.FieldByName('user_name').AsString);
Query.Next;
end;
finally
Query.Free;
end;
...
end;
Можно создавать экземпляр TDISQLite3UniDirQuery динамически (как выше), а можно разместить его на форме и обращаться к его свойствам в редакторе.
Чтобы быть в курсе обновлений блога, можно подписаться на RSS.


Не подскажешь, чем можно синхронизировать БД? Что-то не нашел таких компонентов под delphi. Короче как сделать репликацию sqlite?
ОтветитьУдалитьНе, не знаю, я не писала многопользовательских приложений с sqlite. Может, кто из читателей знает, возможно ли это.
ОтветитьУдалитьZeosDBO хорош, если пользоваться последней версией (альфа,бетта)
ОтветитьУдалитьМожно использовать как визуально так и рантайм немного напугало отсутствие документации но пару форумов поправят это дело
Извините, если Вы уже это знаете... :)
ОтветитьУдалитьДля локальной работы удобно использовать встроенные в Окошки движок базы Access.
Достоинства (в свете использования в Дельфи и распространения):
- Он есть в системе всегда, даже если Офис не установлен.
- Никаких дополнительных компонентов не надо, доступ через ADODataSet.
- Это один файл. Достаточно создать его в Аксесе и приложить к дистрибутиву.
Недостаток: Никаких "серверных" скриптов, триггеров и т.п. нету. Только Запрос/Ответ
FireBird: Опенсорсный наследник Interbase. Полноценная мощная база, с триггерами, функциями и т.д. и т.п.
Никаких специальных компонентов не требуется. Доступ через dbExpress (драйвер Interbase). База - один файл. Можно работать как с локальной базой, так и по сети с сервером. Причем ни базу, ни приложение переделывать не надо, только использовать разные DLLки.
Сергей, спасибо за развернутый комментарий :) Да, я это знаю, как-никак 9 лет преимущественно с базами данных работаю, но, может, кому-то он поможет сделать выбор БД.
Удалитьспасибо за статью! как раз думал с какой стороны подходить к disqlite, уж очень тяжеловесно всё в её родных примерах.
ОтветитьУдалитьНащет AUTOINCREMENT: http://habrahabr.ru/qa/18641/
ОтветитьУдалитьЦитата:
How do I create an AUTOINCREMENT field.
Short answer: A column declared INTEGER PRIMARY KEY will autoincrement.
Про INTEGER PRIMARY KEY есть в посте, зачем дублировать в комментариях? :)
УдалитьВ прдолжение к предыдещему. После использования DISQLite вылазит куча утечек памяти. Как бороться с утечками после DISQLite3Database нарыл на официальном форуме. А вот после TDISQLite3UniDirQuery остается много не унитоженых widestring'ов. Может встречали как с этим бороться? У меня DISQLite3 4.2.0 personal и Delphi XE3
ОтветитьУдалить