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

Планы, идеология, архитектура и т.п.

Модератор: Модераторы

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

Сообщение Vadim » 13.05.2011 16:07:18

Nik писал(а):Я, увы, не знаю такого

Я тоже.
Может просто в цикле сохранять данные в текстовом файле, а потом, так же циклом, считывать?
Vadim
долгожитель
 
Сообщения: 4112
Зарегистрирован: 05.10.2006 08:52:59
Откуда: Красноярск

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

Сообщение Nik » 13.05.2011 16:55:29

Vadim писал(а):
Nik писал(а):Я, увы, не знаю такого

Я тоже.
Может просто в цикле сохранять данные в текстовом файле, а потом, так же циклом, считывать?

Сейчас как раз такой вариант пробую реализовать. С файловым потоком какой-то больно мутный алгоритм получается.
Аватара пользователя
Nik
энтузиаст
 
Сообщения: 573
Зарегистрирован: 04.02.2006 00:08:09
Откуда: Киров

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

Сообщение Vadim » 13.05.2011 19:11:42

Nik
Можно без потока, обычным паскалевским способом - AssignFile(), Rewrite(), WriteLn()...
Vadim
долгожитель
 
Сообщения: 4112
Зарегистрирован: 05.10.2006 08:52:59
Откуда: Красноярск

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

Сообщение Padre_Mortius » 13.05.2011 23:22:07

Результаты запроса лежат в таблице TSQLiteTable. Требуется каким-то образом сохранить эти результаты в файл, а затем загрузить их из файла в другой TSQLiteTable.

TSQLiteTable принадлежат одной базе или разным? Выгрузка в файл обязательна?
Padre_Mortius
энтузиаст
 
Сообщения: 1265
Зарегистрирован: 29.05.2007 17:38:07
Откуда: Спб

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

Сообщение Nik » 14.05.2011 10:46:30

2Padre_Mortius
Они на разных машинах в разных базах. Не обязательно в файл, можно в поток.
Аватара пользователя
Nik
энтузиаст
 
Сообщения: 573
Зарегистрирован: 04.02.2006 00:08:09
Откуда: Киров

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

Сообщение Padre_Mortius » 14.05.2011 17:03:30

а чем не устроил текст с разделителями? вроде бы самое универсальное решение. На его основе уже как хотите так и реализуйте... Хоть поток, хоть файл...
Padre_Mortius
энтузиаст
 
Сообщения: 1265
Зарегистрирован: 29.05.2007 17:38:07
Откуда: Спб

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

Сообщение Nik » 14.05.2011 19:16:08

Padre_Mortius писал(а):а чем не устроил текст с разделителями? вроде бы самое универсальное решение. На его основе уже как хотите так и реализуйте... Хоть поток, хоть файл...

Там свои нюансы. Сохранить в текстовый файл - дело плёвое, но вот обратно в TSQLiteTable правильно развернуть текст пока не получается.
Аватара пользователя
Nik
энтузиаст
 
Сообщения: 573
Зарегистрирован: 04.02.2006 00:08:09
Откуда: Киров

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

Сообщение Padre_Mortius » 14.05.2011 22:11:05

Сложности могут возникнуть только если необходимо исключить импорт повторных записей, или если запись найдена и ее необходимо обновить.
Padre_Mortius
энтузиаст
 
Сообщения: 1265
Зарегистрирован: 29.05.2007 17:38:07
Откуда: Спб

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

Сообщение Nik » 14.05.2011 23:01:26

В данный момент косяк вот в чём. TSQLiteTable хранит данные в виде массива указателей TList. Указатели разных типов. Проблема в том, что если данные сохранять в текстовый файл (штатные методы TSQLiteTable это позволяют через финт ушами), то потом не удаётся в точности восстановить исходный TList, поскольку типы указателей теряются.

Пока пришёл вот к чему. Самым оптимальным способом было бы сохранение данных из TList в том виде, в каком они есть, в TMemoryStream, не приводя их к текстовому виду. Затем, соответственно, всё считать из потока (который можно и через сохранение файл куда-то передать, и по сети без сохранения) и записать в TList.
Разобрать TList на элементы не проблема (свойство Items есть), собрать - тоже. Затык в запись указателей в поток. Я пробовал в лоб:

Код: Выделить всё
fResults: TList;
...
res: TMemoryStream;
...

res.Write(fResults[i]^, SizeOf(fResults[i]));


Но при таком раскладе в потоке оказывается ерунда (что предсказуемо). Если писать fResults[i] - в поток попадают (если я правильно понял) адреса.

Кто-нибудь знает, как корректно записать Pointer неизвестного типа в поток и потом их обратно считать?
Аватара пользователя
Nik
энтузиаст
 
Сообщения: 573
Зарегистрирован: 04.02.2006 00:08:09
Откуда: Киров

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

Сообщение Odyssey » 15.05.2011 14:04:35

Ветка о сохранении списка указателей в поток - тут:
viewtopic.php?t=7045

А вообще, можно всё то же самое сделать средствами SQL:
http://www.sqlite.org/lang_createtable.html
Искать по "CREATE TABLE ... AS SELECT"

причём можно сохранить новую таблицу даже в новую отдельную базу данных, подключенную через ATTACH DATABASE (http://www.sqlite.org/lang_attach.html). И тогда полученный файл базы можно пересылать и вливать в другую базу через
INSERT INTO ... SELECT FROM ...
http://www.sqlite.org/lang_insert.html
Искать по "The second form of the INSERT statement"
Odyssey
энтузиаст
 
Сообщения: 580
Зарегистрирован: 29.11.2007 17:32:24

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

Сообщение Nik » 15.05.2011 14:51:46

2Odyssey
Спасибо за наводку! Пожалуй, через временную ДБ будет проще реализовать. Буду копать в эту сторону. Собственно, уже разобрался, как подключить временную ДБ, осталось как-то в неё перенести результаты выборки.

Добавлено спустя 44 минуты 32 секунды:
Никак не получается записать что-либо во временную БД. Выполняю такой код:

Код: Выделить всё
  SQL_db.ExecSQL('ATTACH ''c:temp.db3'' AS tmp_db');

if not (SQL_db.TableExists('tmp_table')) then
  begin
   SQL_query:='CREATE TABLE IF NOT EXISTS [tmp_table] ([id] INTEGER, [name] CHAR, [parent] INTEGER, [cat_order] INTEGER)';
   SQL_db.execsql(SQL_query);
   SQL_db.ExecSQL('INSERT INTO tmp_table (id, name, parent, cat_order) VALUES ("0", "Тестовая категория", "-1", "0")');
  end; 


Файл новой БД создаётся, но какие бы команды не выполнялись, его размер остаётся 0 байт. Пробовал и явно обращаться к таблицам (tmp_db.tmp_table) и просто по имени (судя по описанию на сайте SQLite при отсутствии в основной и временной БД одноимённых таблиц можно обращаться к таблицам просто по имени - без префикса). Отрабатывает только код создания таблиц - но таблицы создаются в основной БД (даже при явном задании префикса с именем временной БД - в этом случае в основной ДБ создаются таблицы с именем типа tmp_db.tmp_table, включающим и префикс тоже).

Добавлено спустя 33 минуты 23 секунды:
Всё, кажется разобрался. В итоге получилось вот что:

Код: Выделить всё
// Цепляем временную БД
SQL_db.ExecSQL('ATTACH "c:send.db3" AS xdb');

// Делаем выборку из основной БД и сохраняем её во временную
SQL_query:='CREATE TABLE [xdb].[myres] AS SELECT * FROM rashod WHERE bill=1';
SQL_db.execsql(SQL_query);


2Odyssey: ещё раз спасибо :)

Добавлено спустя 12 минут 52 секунды:
PS. Уже просто из спортивного интереса подумал: как бы сделать всё то же самое без сохранения файла на диск? SQLite позволяет создавать БД в памяти, но до такой БД вряд ли удастся добраться с целью сохранения в TMemoryStream.
Аватара пользователя
Nik
энтузиаст
 
Сообщения: 573
Зарегистрирован: 04.02.2006 00:08:09
Откуда: Киров

Пред.

Вернуться в Разработки на нашем сайте

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 0

Рейтинг@Mail.ru