Russian Qt Forum
Ноябрь 22, 2024, 11:21 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: 1 2 [3]   Вниз
  Печать  
Автор Тема: QST: QsT SQL Tools  (Прочитано 47332 раз)
vlad-mal
Гость
« Ответ #30 : Ноябрь 13, 2010, 17:38 »

...
Судя по тому что Вы называете ORM костылем у Вас либо был неудачный опыт в этом деле и Вы его неправильно готовили, либо Вы просто не имеете большого опыта в этой теме.
...
Определенно, какие-то причины были. Улыбающийся
Записан
mapron
Гость
« Ответ #31 : Ноябрь 13, 2010, 21:44 »

Итак, товарищи, свершилось! я закончил работу по реализации связи между моделями. Пока что поддерживается только HasMany, да и то только первого уровня, но сделано таким образом что доработать все остальное не составит проблем.
Как это работает?
1. Создаем реестр моделей в статичной функции init класса Model:
Код
C++ (Qt)
void Model::init(QString connection)
{
   collection.clear();
   collection.insert("user", new ModelUser(connection)); // пользователь
   collection.insert("session", new ModelSession(connection)); // у пользователя есть его сессии
   collection.insert("submission",new  ModelSubmission(connection)); // и его "решения"
}
 
Минус здесь в том, что используются указатели Грустный. Это теоретически возможные проблемы с памятью и тп.

2. Создаем нужную модель и связываем ее с другими
Код
C++ (Qt)
ModelUser::ModelUser(QString connection):Model(connection)
{
 useTable="users";
 addLink(LT_HasMany,"session", "id","uid");  // связываем модели здесь. Минус - использование константы
 addLink(LT_HasMany,"submission", "id","uid");
}
 
я уже подумываю об использовании различных методов для различных связей. т.е. addLinkHasMany и тп

3. Используем метод модели для получения зависимых данных (пока это тот же fetchAll)
Код
C++ (Qt)
ModelUser u;
Var res=u.fetchAll(Var(),1); // прототип Var Model::fetchAll(Var where,int depth)
 

На выходе получаем примерно такой объект (пользователь в данном случае один, но с многими тоже работает) (преобразован в JSON для наглядности)
Код
Javascript
[ {
"_session" : [ {
"id" : "1",
"last_hit" : "2010-11-14 01:46:43",
"sid" : "93968137971e79d5b7b0c9451ecb8bb2",
"uid" : "1"
}, {
"id" : "2",
"last_hit" : "2010-11-14 01:47:17",
"sid" : "77e70c5045398b09204af9e9d29002e9",
"uid" : "1"
} ],
"_submission" : [ {
"id" : "1",
"lang_id" : "1",
"message" : "undefined reference to `main`",
"send" : "2010-11-11 23:43:41",
"status" : "2",
"task_id" : "1",
"txt" : "#include <iostream>\nint main (int argc, char* argv [])\n{\nstd::cout << \"Hello, world!\" << std::endl;\nreturn 0;\n}",
"uid" : "1"
} ],
"famil" : "Фамилия",
"id" : "1",
"ima" : "Имя",
"login" : "user",
"otch" : "Отчество",
"passhash" : "d8578edf8458ce06fbc5bb76a58c5ca4",
"rights" : "1"
} ];
 

Что думаете, товарищи? Давайте вместе придумаем "идеальную" в использовании систему. Вы можете предложить удобный для вас синтаксис выполнения различных действий? В идеале крое автокоплита для написания кода больше ничего не нужно.
« Последнее редактирование: Ноябрь 14, 2010, 11:38 от mapron » Записан
GraninAS
Гость
« Ответ #32 : Ноябрь 15, 2010, 11:31 »

Я думаю, что это правильно - много разных разработок с разной философией. Каждый выбирает себе по вкусу и потребностям.

Я так же не согласен с мнением, что ORM - это костыли. Это подход, инструмент. Все спорщики ORM vs. PlainSQL прекрасно это понимают, но холивары всё равно вспыхивают тут и там. Подозреваю, что здесь вот-вот тоже готова будет завязаться драка. Я бы не хотел. Не в этой теме. Заведите другую тему, и я тоже присоединюсь к дискуссии, если позволит время.

Уважаемому mapron'у желаю всяческих успехов.

Пару вопросов я задам.

1. Вы говорите, что функция void Model::init(QString connection) статическая. Вероятно, она должна обращаться к статическому члену collection. Что это дает?

2. Передается некая строка connection. Что происходит с ней дальше? Вообще, как происходит подсоединение к базе данных и извлечение самих данных?
Записан
mapron
Гость
« Ответ #33 : Ноябрь 15, 2010, 14:06 »

Подозреваю, что здесь вот-вот тоже готова будет завязаться драка. Я бы не хотел. Не в этой теме.
Да такого вроде не было, мы пришли к общему мнению: vlad-mal, признался что у него был неудачный опыт. В чем сочувствую ему.
Так можно и отверткой себя в глаз нечаянно ткнуть и холиварить потом "отвертки ацтой!"

Пару вопросов я задам.
1. Вы говорите, что функция void Model::init(QString connection) статическая. Вероятно, она должна обращаться к статическому члену collection. Что это дает?
collection - это статический член, где содержатся все объекты всех используемых моделей. в QxORM тоже подобная штука есть, как выяснилась, только заполняется она с помощью создания шаблонных классов вроде.
Зачем статичная? чтобы не создавать объекты моделей при циклических/рекурсивных вызовах внутри ORM.
Зачем хранить их в списке? чтобы иметь соответствие имя модели=> объект.

2. Передается некая строка connection. Что происходит с ней дальше? Вообще, как происходит подсоединение к базе данных и извлечение самих данных?

Подсоединение к базе остается за рамками ORM. это DAL все же. поэтому акцент чисто на модель. Без отображения и т.п.
Вот пример кода соединения с базой данных
Код
C++ (Qt)
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE",QLatin1String( QSqlDatabase::defaultConnection ));
db.setDatabaseName("db.sqlite");
   QSqlDatabase db1 = QSqlDatabase::addDatabase("QSQLITE","thread1");
   db1.setDatabaseName("db.sqlite");
   QSqlDatabase db2 = QSqlDatabase::addDatabase("QSQLITE","thread2");
   db2.setDatabaseName("db.sqlite");
 
Видно, конечно, что не правильно и не аккуратно. Здесь я использую встроенные возможность qt без оберток. все же баз данных и подключений в моем проекте не так уж и много.
Запуск статичного метода (при старте веб-сервера у меня) - это тоже уже детали.
Код:
Model::init();
То же самое при инициализации потока:
Код:
Model::init("thread1");
Это делать необязательно, только для работы именно с ORM-возможностями.

Извлечение самих данных происходит при вызове методов объекта
вот список публичных методов модели:
Код
C++ (Qt)
   // извлечение строки
   Var fetchRow(QString querytext, Var bind);
   Var fetchRow(Var where);
   Var fetchById(int id);
   Var fetchById(QString id);
 
   // извлечение набора строк
   Var fetchAll(Var where,QString order="",int limit=0,int offset=0, int depth=0);
   Var fetchAll(Var where,int depth);
   Var fetchAll(QString querytext, Var bind);
 
   // вставка записи
   int insert(Var record);
   // обновление записи
   int update(Var record,int id);
   int update(Var record,Var where);
   // удаление
   int delet(int id);
   int delet(Var where);
 
   void truncate();// очистка
   // добавление связи с другими моделями
   void addLink(LinkingType link_type, QString dest_model, QString source_key, QString dest_key);
 


PS. offtopic. вот интересно, пост Александра датирован сегодня 11:31, а мой ответ на него тоже сегодня 02:32. Интересные дела.
« Последнее редактирование: Ноябрь 15, 2010, 14:09 от mapron » Записан
mapron
Гость
« Ответ #34 : Ноябрь 16, 2010, 14:11 »

Хм, я понял только что серьезную ошибку: потоко-небезопасность моего решения... Model::init() какой-то непрвильный метод. Подключение к бд - это не thread-safe, но шаринг я реализовал тоже неправильно. Буду делать работу над Ошибками.
Как все закончу, создам новый топик и выложу на всеобщее оборзение. И не буду больше мусроить здесь автору Улыбающийся честно Улыбающийся
Записан
pepsil
Гость
« Ответ #35 : Июль 16, 2011, 16:14 »

Здравствуйте!
В аннотации к релизу 0.5.9.5a написано, что сделано компатибилити с Qt4.6

Changes from QST 0.5.9.5 release
- Compatibility errors with Qt 4.6.x are fixed.

При сборке на 4.6.2 есть ошибка:
qst\common\treeitem.cpp: In member function 'void Qst::Common::TreeItem::setData(const int&, const QVariant&, int)':
qst\common\treeitem.cpp:217: error: 'class QList<QVariant>' has no member named 'reserve'

смотрел документацию, таки да, функция-член reserve появилась с версии 4.7
Подскажите, пожалуйста, из какой версии QST можно выбрать код для TreeItem чтобы не использовать reverse (для сборки  с Qt 4.6.2)?
Записан
GraninAS
Гость
« Ответ #36 : Июль 17, 2011, 15:06 »

Здравствуйте!

Спасибо за отзыв. Я завтра посмотрю, - видимо, я очень плохо тестил эту версию. Думал, что исправил все несовместимости. Завтра исправлю и выложу для вас код, потому что, похоже, в других версиях всё так же.

С уважением.
Записан
GraninAS
Гость
« Ответ #37 : Июль 18, 2011, 07:28 »

Еще раз приветствую!

Я посмотрел свой код. В нем эта проблемная строчка закоменчена, код переписан. Компилируется. Значит, я мог забыть закомитить код в репозиторий или в архивы. Слил 7z-архив, там тоже код переписан. В репозитории  тоже свежая, с нужной правкой, ревизия 24. Можете взять код в виде архива (tar.gz, zip, rarб 7z) или слить его с SVN.

Спасибо!

---------------------

Не отходя от кассы, сообщаю, что наконец-то победил генерацию сложных запросов. За прошедшую неделю сделал то, что не мог сделать два месяца или около того. Основательно перерабатываю QST в версии 0.6, будут большие архитектурные изменения, без которых не получается. К сожалению, не все обратно совместимы, так что старый код будет нужно исправить.
« Последнее редактирование: Июль 18, 2011, 07:30 от GraninAS » Записан
Страниц: 1 2 [3]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.179 секунд. Запросов: 21.