Skip to content

sync_schema ignores the addition of foreign keys, and incorrect insert statement #790

@khgreav

Description

@khgreav

Hi, first and foremost, thanks for the library as I haven't seen too many usable ones around.

Now to get my issue, I've been playing with the library and testing it for a bit on and off. Yesterday, I came across 2 issues.
To illustrate, I've put together a small example below.

I tend to use class-based entities, but that shouldn't be an issue, at least I never found one up until now.

#include <sqlite_orm/sqlite_orm.h>
#include <iostream>

using namespace sqlite_orm;

class A {
public:
	A() = default;
	A(const uint8_t &a) : a(a) {};

	const uint32_t& getId() const {
		return this->id;
	}

	void setId(const uint32_t &id) {
		this->id = id;
	}

	const uint8_t& getA() const {
		return this->a;
	}

	void setA(const uint8_t &a) {
		this->a = a;
	}
private:
	uint32_t id;
	uint8_t a;
};

class B {
public:
	B() = default;
	B(const uint8_t &b) : b(b) {};

	const uint32_t& getId() const {
		return this->id;
	}

	void setId(const uint32_t &id) {
		this->id = id;
	}

	const uint8_t& getB() const {
		return this->b;
	}

	void setB(const uint8_t &b) {
		this->b = b;
	}
private:
	uint32_t id;
	uint8_t b;
};

class C {
public:
	C() = default;
	C(const uint32_t &aId, const uint32_t &bId) : aId(aId), bId(bId) {};

	const uint32_t& getAId() const {
		return this->aId;
	}

	void setAId(const uint32_t &aId) {
		this->aId = aId;
	}

	const uint32_t& getBId() const {
		return this->bId;
	}

	void setBId(const uint32_t &bId) {
		this->bId = bId;
	}
private:
	uint32_t aId;
	uint32_t bId;
};

static auto initExample(const std::string &file) {
	return make_storage(file,
		make_table("A",
			make_column("id", &A::getId, &A::setId, primary_key(), autoincrement()),
			make_column("a", &A::getA, &A::setA)
		),
		make_table("B",
			make_column("id", &B::getId, &B::setId, primary_key(), autoincrement()),
			make_column("b", &B::getB, &B::setB)
		),
		make_table("C",
			make_column("aId", &C::getAId, &C::setAId),
			make_column("bId", &C::getBId, &C::setBId),
			primary_key(&C::getAId, &C::getBId),
			foreign_key(&C::getAId).references(&A::getId), // added later once the table was already created
			foreign_key(&C::getBId).references(&B::getId) //added later once the table was already created
		)
	);
}

using Db = decltype(initExample(""));

static void example(const std::string &path) {
	std::unique_ptr<Db> db = std::make_unique<Db>(initExample(path));
	auto res = db->sync_schema();
	A a(5);
	B b(10);
	uint32_t aId, bId;
	try {
		aId = db->insert(a);
		bId = db->insert(b);
	} catch (const std::system_error &e) {
		//
	}
	try {
		C c(aId, bId);
		db->insert(c);
	} catch (const std::system_error &e) {
		//
	}
}
  1. It seems that sync_schema() ignores addition of foreign keys once a table has been created previously. When I first created entity and table C, the foreign keys were not included, after adding foreign keys and calling sync_schema(), the return value reports all tables as already_in_sync. Removing the database file and letting it be created again from scratch results in the desired composite and foreign keys.

  2. Table C exists to match records from A and B, however, the insert statement fails. After debugging the code, I found out that the serialized statement to be executed is this: "INSERT INTO 'C' DEFAULT VALUES ".

Am I doing this wrong? Thanks for the help in advance.

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions