Skip to content

Commit

Permalink
added if_exists with tests
Browse files Browse the repository at this point in the history
  • Loading branch information
fnc12 committed Jul 13, 2024
1 parent 64342a0 commit 8fadf9e
Show file tree
Hide file tree
Showing 4 changed files with 197 additions and 30 deletions.
4 changes: 2 additions & 2 deletions dev/storage.h
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ namespace sqlite_orm {
template<class Table>
void drop_create_with_loss(sqlite3* db, const Table& table) {
// eliminated all transaction handling
this->drop_table_internal(db, table.name);
this->drop_table_internal(db, table.name, false);
this->create_table(db, table.name, table);
}

Expand All @@ -176,7 +176,7 @@ namespace sqlite_orm {

this->copy_table(db, table.name, backupTableName, table, columnsToIgnore);

this->drop_table_internal(db, table.name);
this->drop_table_internal(db, table.name, false);

this->rename_table(db, backupTableName, table.name);
}
Expand Down
90 changes: 77 additions & 13 deletions dev/storage_base.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,27 +70,66 @@ namespace sqlite_orm {
std::bind(&storage_base::rollback, this)};
}

/**
* Drops index with given name.
* Calls `DROP INDEX indexName`.
* More info: https://www.sqlite.org/lang_dropindex.html
*/
void drop_index(const std::string& indexName) {
std::stringstream ss;
ss << "DROP INDEX " << quote_identifier(indexName) << std::flush;
perform_void_exec(this->get_connection().get(), ss.str());
this->drop_index_internal(indexName, false);
}

/**
* Drops trigger with given name if trigger exists.
* Calls `DROP INDEX IF EXISTS indexName`.
* More info: https://www.sqlite.org/lang_dropindex.html
*/
void drop_index_if_exists(const std::string& indexName) {
this->drop_index_internal(indexName, true);
}

/**
* Drops trigger with given name.
* Calls `DROP TRIGGER triggerName`.
* More info: https://www.sqlite.org/lang_droptrigger.html
*/
void drop_trigger(const std::string& triggerName) {
std::stringstream ss;
ss << "DROP TRIGGER " << quote_identifier(triggerName) << std::flush;
perform_void_exec(this->get_connection().get(), ss.str());
this->drop_trigger_internal(triggerName, false);
}

/**
* Drops trigger with given name if trigger exists.
* Calls `DROP TRIGGER IF EXISTS triggerName`.
* More info: https://www.sqlite.org/lang_droptrigger.html
*/
void drop_trigger_if_exists(const std::string& triggerName) {
this->drop_trigger_internal(triggerName, true);
}

/**
* `VACUUM` query.
* More info: https://www.sqlite.org/lang_vacuum.html
*/
void vacuum() {
perform_void_exec(this->get_connection().get(), "VACUUM");
}

/**
* Drops table with given name.
* Drops table with given name.
* Calls `DROP TABLE tableName`.
* More info: https://www.sqlite.org/lang_droptable.html
*/
void drop_table(const std::string& tableName) {
this->drop_table_internal(this->get_connection().get(), tableName);
this->drop_table_internal(this->get_connection().get(), tableName, false);
}

/**
* Drops table with given name if table exists.
* Calls `DROP TABLE IF EXISTS tableName`.
* More info: https://www.sqlite.org/lang_droptable.html
*/
void drop_table_if_exists(const std::string& tableName) {
this->drop_table_internal(this->get_connection().get(), tableName, true);
}

/**
Expand Down Expand Up @@ -885,15 +924,40 @@ namespace sqlite_orm {
return result;
}

void drop_table_internal(sqlite3* db, const std::string& tableName) {
void drop_table_internal(sqlite3* db, const std::string& tableName, bool ifExists) {
std::stringstream ss;
ss << "DROP TABLE " << streaming_identifier(tableName) << std::flush;
ss << "DROP TABLE";
if(ifExists) {
ss << " IF EXISTS";
}
ss << streaming_identifier(tableName) << std::flush;
perform_void_exec(db, ss.str());
}

static int collate_callback(void* arg, int leftLen, const void* lhs, int rightLen, const void* rhs) {
auto& f = *(collating_function*)arg;
return f(leftLen, lhs, rightLen, rhs);
void drop_index_internal(const std::string& indexName, bool ifExists) {
std::stringstream ss;
ss << "DROP INDEX";
if(ifExists) {
ss << " IF EXISTS";
}
ss << quote_identifier(indexName) << std::flush;
perform_void_exec(this->get_connection().get(), ss.str());
}

void drop_trigger_internal(const std::string& triggerName, bool ifExists) {
std::stringstream ss;
ss << "DROP TRIGGER";
if(ifExists) {
ss << " IF EXISTS";
}
ss << quote_identifier(triggerName) << std::flush;
perform_void_exec(this->get_connection().get(), ss.str());
}

static int
collate_callback(void* argument, int leftLength, const void* lhs, int rightLength, const void* rhs) {
auto& function = *(collating_function*)argument;
return function(leftLength, lhs, rightLength, rhs);
}

static int busy_handler_callback(void* selfPointer, int triesCount) {
Expand Down
94 changes: 79 additions & 15 deletions include/sqlite_orm/sqlite_orm.h
Original file line number Diff line number Diff line change
Expand Up @@ -17701,27 +17701,66 @@ namespace sqlite_orm {
std::bind(&storage_base::rollback, this)};
}

/**
* Drops index with given name.
* Calls `DROP INDEX indexName`.
* More info: https://www.sqlite.org/lang_dropindex.html
*/
void drop_index(const std::string& indexName) {
std::stringstream ss;
ss << "DROP INDEX " << quote_identifier(indexName) << std::flush;
perform_void_exec(this->get_connection().get(), ss.str());
this->drop_index_internal(indexName, false);
}

/**
* Drops trigger with given name if trigger exists.
* Calls `DROP INDEX IF EXISTS indexName`.
* More info: https://www.sqlite.org/lang_dropindex.html
*/
void drop_index_if_exists(const std::string& indexName) {
this->drop_index_internal(indexName, true);
}

/**
* Drops trigger with given name.
* Calls `DROP TRIGGER triggerName`.
* More info: https://www.sqlite.org/lang_droptrigger.html
*/
void drop_trigger(const std::string& triggerName) {
std::stringstream ss;
ss << "DROP TRIGGER " << quote_identifier(triggerName) << std::flush;
perform_void_exec(this->get_connection().get(), ss.str());
this->drop_trigger_internal(triggerName, false);
}

/**
* Drops trigger with given name if trigger exists.
* Calls `DROP TRIGGER IF EXISTS triggerName`.
* More info: https://www.sqlite.org/lang_droptrigger.html
*/
void drop_trigger_if_exists(const std::string& triggerName) {
this->drop_trigger_internal(triggerName, true);
}

/**
* `VACUUM` query.
* More info: https://www.sqlite.org/lang_vacuum.html
*/
void vacuum() {
perform_void_exec(this->get_connection().get(), "VACUUM");
}

/**
* Drops table with given name.
* Drops table with given name.
* Calls `DROP TABLE tableName`.
* More info: https://www.sqlite.org/lang_droptable.html
*/
void drop_table(const std::string& tableName) {
this->drop_table_internal(this->get_connection().get(), tableName);
this->drop_table_internal(this->get_connection().get(), tableName, false);
}

/**
* Drops table with given name if table exists.
* Calls `DROP TABLE IF EXISTS tableName`.
* More info: https://www.sqlite.org/lang_droptable.html
*/
void drop_table_if_exists(const std::string& tableName) {
this->drop_table_internal(this->get_connection().get(), tableName, true);
}

/**
Expand Down Expand Up @@ -18516,15 +18555,40 @@ namespace sqlite_orm {
return result;
}

void drop_table_internal(sqlite3* db, const std::string& tableName) {
void drop_table_internal(sqlite3* db, const std::string& tableName, bool ifExists) {
std::stringstream ss;
ss << "DROP TABLE " << streaming_identifier(tableName) << std::flush;
ss << "DROP TABLE";
if(ifExists) {
ss << " IF EXISTS";
}
ss << streaming_identifier(tableName) << std::flush;
perform_void_exec(db, ss.str());
}

static int collate_callback(void* arg, int leftLen, const void* lhs, int rightLen, const void* rhs) {
auto& f = *(collating_function*)arg;
return f(leftLen, lhs, rightLen, rhs);
void drop_index_internal(const std::string& indexName, bool ifExists) {
std::stringstream ss;
ss << "DROP INDEX";
if(ifExists) {
ss << " IF EXISTS";
}
ss << quote_identifier(indexName) << std::flush;
perform_void_exec(this->get_connection().get(), ss.str());
}

void drop_trigger_internal(const std::string& triggerName, bool ifExists) {
std::stringstream ss;
ss << "DROP TRIGGER";
if(ifExists) {
ss << " IF EXISTS";
}
ss << quote_identifier(triggerName) << std::flush;
perform_void_exec(this->get_connection().get(), ss.str());
}

static int
collate_callback(void* argument, int leftLength, const void* lhs, int rightLength, const void* rhs) {
auto& function = *(collating_function*)argument;
return function(leftLength, lhs, rightLength, rhs);
}

static int busy_handler_callback(void* selfPointer, int triesCount) {
Expand Down Expand Up @@ -22059,7 +22123,7 @@ namespace sqlite_orm {
template<class Table>
void drop_create_with_loss(sqlite3* db, const Table& table) {
// eliminated all transaction handling
this->drop_table_internal(db, table.name);
this->drop_table_internal(db, table.name, false);
this->create_table(db, table.name, table);
}

Expand All @@ -22086,7 +22150,7 @@ namespace sqlite_orm {

this->copy_table(db, table.name, backupTableName, table, columnsToIgnore);

this->drop_table_internal(db, table.name);
this->drop_table_internal(db, table.name, false);

this->rename_table(db, backupTableName, table.name);
}
Expand Down
39 changes: 39 additions & 0 deletions tests/storage_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,45 @@ TEST_CASE("drop table") {
storage.drop_table(visitsTableName);
REQUIRE_FALSE(storage.table_exists(usersTableName));
REQUIRE_FALSE(storage.table_exists(visitsTableName));

REQUIRE_THROWS(storage.drop_table(usersTableName));
REQUIRE_THROWS(storage.drop_table(visitsTableName));

REQUIRE_NOTHROW(storage.drop_table_if_exists(usersTableName));
REQUIRE_NOTHROW(storage.drop_table_if_exists(visitsTableName));
}

TEST_CASE("drop index") {
struct User {
int id = 0;
std::string name;
};
const std::string indexName = "user_id_index";
auto storage = make_storage(
{},
make_index("user_id_index", &User::id),
make_table("users", make_column("id", &User::id, primary_key()), make_column("name", &User::name)));
storage.sync_schema();

REQUIRE_NOTHROW(storage.drop_index(indexName));
REQUIRE_THROWS(storage.drop_index(indexName));
REQUIRE_NOTHROW(storage.drop_index_if_exists(indexName));
}

TEST_CASE("drop trigger") {
struct User {
int id = 0;
std::string name;
};
const std::string triggerName = "table_insert_InsertTest";
auto storage = make_storage(
{},
make_trigger(triggerName, after().insert().on<User>().begin(update_all(set(c(&User::id) = 5))).end()),
make_table("users", make_column("id", &User::id, primary_key()), make_column("name", &User::name)));
storage.sync_schema();
REQUIRE_NOTHROW(storage.drop_trigger(triggerName));
REQUIRE_THROWS(storage.drop_trigger(triggerName));
REQUIRE_NOTHROW(storage.drop_trigger_if_exists(triggerName));
}

TEST_CASE("rename table") {
Expand Down

0 comments on commit 8fadf9e

Please sign in to comment.