Pull to refresh
2
0

Пользователь

Send message

А, Вы про то, что в базе написано categoryId, а в структуре category, например?

Я так и понял, я не понял к чему тогда относился комментарий


структуры схеме не соответствуют
когда классы соответствуют схеме

Я хотел лишь сказать, что если я захочу добавить в структуру какое-то поле, например, немного надуманное поле shouldHavePassport пользователю, которое не хранится в БД, а вычисляется в триггере или еще где-нибудь потом как user.age >= 14 или еще и учитывает страну, то будет нелогично не добавлять его в структуру. Его стоит указать несериализуемым, да, но добавлять в структуру просто необходимо, в то время как к базе оно может не иметь никакого отношения.


идеально иллюстрирует вложенный запрос

О, спасибо, теперь я понял что мне напомнила ваша ORM. Текстовое представление regexp'ов


Я думал добавить сырые С-указатели, но этого не будет

Правильно, не надо, мы живем в С++1(4|7)


тут надо подумать

Тут думать не передумать. Посмотрите в строну sequelize. К сожалению, не все их решения можно перевести на С++, но как позаимствовать идеи, синтаксис и некоторые фичи — очень полезно будет

Разумеется, так можно. И нужно делать именно так, если ORM не поддерживает вложенные сущности. Но, согласитесь, хочется спихнуть весь этот (можно сказать служебный и практически ненужный) код на ORM


структуры схеме не соответствуют

Все правильно, они и не должны. Если я хочу добавить transient поле в структуру, я его туда добавлю, но не буду добавлять в make_column. Ну и по-хорошему в структуре пометить их комментарием, что они не сериализуются.


Здесь еще тонкий момент со связями не многие-ко-многим. Придется писать в структуре или experimental::optional<T> или, как в вашем решении std::shared_ptr<T>, что, безусловно, снизит читаемость кода

В каком-нибудь таком:
struct Category;

struct Book {
    int id;
    std::string name;
    int createdAt;
    std::vector<Category> categories;
};

struct Category {
    int id;
    std::string name;
    std::vector<Book> books;
};

И что-нибудь типа такого в описании:
make_table("books", make_many_to_many_association("categories", &Book::categories, &Category::books, through(&BookCategories)));

Тут скорее всего надо еще руками определить `BookCategories` и привязывать не к `&Category::books` а к `&BookCategories::bookId`, но в идеале это делать автоматически.
Пишу «типа такого», потому что если бы у меня было четкое представление как это сделать, я бы это давно уже сделал ;)
Я сейчас говорил не о именно sqlite3, просто о БД. Но не думаю, что таких кейсов использования нет в embedded

Вы все сами уже ниже описали ;)
CREATE TABLE books(id INTEGER PRIMARY KEY, name TEXT);
CREATE TABLE categories(id INTEGER PRIMARY KEY, name TEXT)
CREATE TABLE books_categories(category_id INTEGER, book_id INTEGER)

Ничего хитрее я не имел в виду
Вы немного неправильно меня поняли, я имел в виду связь между книгой и категорией многие-ко-многим (+сущность BookCategory с соответствующими айдишниками) и, соответственно, выдирать категории именно для конкретной книги, к которой они привязаны. Для этого случая ваш код еще больше усложнится и будет еще менее поддерживаемый.

Я понимаю, что пока Вы такие случаи не рассматриваете, но они встречаются очень часто в реальной жизни. Как ORM для несвязанных между собой таблиц получилось неплохо, и, надеюсь, полностью покрывает ваши нужды ;)
Да, Вы все правильно поняли. Это в том числе работает со связями многие-ко-многим и рекурсивно. Например, получить 10 книг, отсортированных по дате создания, у каждой получить по 3 категории, которые не имеют родителя. Это, разумеется, просто сделать руками, но в sequelize-like синтаксисе будет выглядеть примерно так:
Book.findAll({
    limit: 10,
    order: [['createdAt', 'DESC']],
    include: [{
        model: Category,
        as: 'categories',
        limit: 3,
        where: {
            parentId: null
        },
        attributes: ['id', 'title'] //Зачем получать лишнюю информацию из базы?
    }]
});
Да, понятно, что сделать несложно. Но, в целом, в качестве связей для меня больше важна возможность достать связанные foreign keyем сущности, нежели чем ограничение существования той самой связанной сущности

Просто я тоже искал «идеальную» ORM для с++, но ничего «годного» не нашел. Вы пытаетесь сделать решение, лучшее, чем существующие, и в этом случае без этих фич никуда. Попробовав, например, hibernate для java или sequelize для node.js вряд ли Вы будете делать запросы руками, которые за Вас может сделать ORM, даже если это просто. Я бы с радостью перевел некоторые свои поделки на с++, как на свой первый и «родной» язык, но пока все ORM, на которые я смотрел имеют только лишь недостатки. Select у Вас выглядит, действительно, очень хорошо, но, согласитесь, достаточно узкая специализация получилась, без join'ов, и, как уже указано leschenko group by и select field1, field2… а не select * (и, кстати, offset'а)
а как же… связи?
Да, с поиском, действительно, все просто

Спасибо, сами того не зная, Вы натолкнули, как мне кажется, на правильное решение моей задачи)
Хотелось бы поскорее уже во всю мощь потрогать руками связку vinyl + sql!

А как Вы эффективно сортируете данные по разным полям?
Единственное решение, которое я сейчас вижу(и использую) это создание индексов для всех полей, по которым надо сортировать(+если используется выборка по полю 1, а сортировка нужна по полю 2 или 3, приходится создавать 2 индекса: 1, 2 и 1, 3)
В таком случае получается достаточно много индексов, а также накладывается ограничение, что это поле не может содержать nil
Уже с сентября прошлого года в бете версии 1.7.* tarantool'а, а также есть слухи о тестировании и скором выходе версии 1.8 с поддержкой sql. Насколько будет оправдан переход на эти версии и насколько будет сложна миграция между ними?
2

Information

Rating
Does not participate
Location
Санкт-Петербург, Санкт-Петербург и область, Россия
Registered
Activity