Для тех, кто случайно наткнулся на эту статью. Я хочу провести эксперимент с продвижением в социальной сети 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
ОтветитьУдалить