diff --git a/server/inc/sql.hpp b/server/inc/sql.hpp index 9c39099..3e32fbc 100644 --- a/server/inc/sql.hpp +++ b/server/inc/sql.hpp @@ -1,20 +1,25 @@ #include -const char create_table[] = "CREATE TABLE IF NOT EXISTS prim_table ( ID INTEGER PRIMARY KEY, USER_ID INTEGER, GEN INTEGER, HASH INTEGER, POS INTEGER, LIKED INTEGER, CHECKED INTEGER);"; +const char create_like_table[] = "CREATE TABLE IF NOT EXISTS like_table ( ID INTEGER PRIMARY KEY, USER_TABLE_ID INTEGER, HASH INTEGER, POS INTEGER, LIKED INTEGER);"; -const char create_index[] = "CREATE INDEX IF NOT EXISTS idx_usrer_id ON prim_table (USER_ID);"; +const char create_user_table[] = "CREATE TABLE IF NOT EXISTS user_table ( ID INTEGER PRIMARY KEY, USER_ID INTEGER, GEN INTEGER, CHECKED INTEGER);"; -const char insert_data[] = "INSERT INTO prim_table (USER_ID, GEN, HASH, POS, LIKED, CHECKED) VALUES(?, ?, ?, ?, ?, 0);"; +const char max_gen[] = "SELECT MAX(GEN) FROM user_table WHERE USER_ID = ?;"; -const char max_gen[] = "SELECT MAX(GEN) FROM prim_table WHERE USER_ID = ?;"; +const char insert_user_data[] = "INSERT INTO user_table (USER_ID, GEN, CHECKED) VALUES(?, ?, 0);"; -const char get_unchecked[] = "SELECT USER_ID FROM prim_table WHERE CHECKED = 0 GROUP BY USER_ID;"; +const char insert_like_data[] = "INSERT INTO like_table (USER_TABLE_ID, HASH, POS, LIKED) VALUES(?, ?, ?, ?);"; -const char get_gen[] = "SELECT HASH, POS, LIKED FROM prim_table WHERE USER_ID = ? AND GEN = ? ORDER BY POS ASC;"; +const char get_unchecked[] = "SELECT USER_ID FROM user_table WHERE CHECKED = 0;"; -const char remove_gen[] = "DELETE FROM prim_table WHERE USER_ID = ? AND GEN >= ?;"; +const char get_gen[] = "SELECT lt.HASH, lt.POS, lt.LIKED FROM like_table lt JOIN user_table ut ON lt.USER_TABLE_ID = ut.ID WHERE ut.USER_ID = ? AND ut.GEN = ? ORDER BY lt.POS ASC;"; -const char set_checked[] = "UPDATE prim_table SET CHECKED = 1 WHERE USER_ID = ? AND GEN = ?;"; +const char get_user_table_id[] = "SELECT ID FROM user_table WHERE USER_ID = ? AND GEN = ?;"; + +const char rem_like_w_user_table_id[] = "DELETE FROM like_table WHERE USER_TABLE_ID = ?;"; +const char rem_user_table_id[] = "DELETE FROM user_table WHERE ID = ?;"; + +const char set_checked[] = "UPDATE user_table SET CHECKED = 1 WHERE USER_ID = ? AND GEN = ?;"; constexpr char DB_NAME[] = "data.db"; @@ -39,4 +44,5 @@ namespace sql int reset(sqlite3_stmt *pStmt); int close(sqlite3 *db); const char *errmsg(sqlite3 *db); + int64_t last_insert_rowid(sqlite3 *db); } diff --git a/server/src/checker.cpp b/server/src/checker.cpp index 42c4d5e..581e368 100644 --- a/server/src/checker.cpp +++ b/server/src/checker.cpp @@ -23,8 +23,14 @@ void checker() sqlite3_stmt *get_gen_stmt; sql::prepare_v2(db, get_gen, -1, &get_gen_stmt, NULL); - sqlite3_stmt *remove_gen_stmt; - sql::prepare_v2(db, remove_gen, -1, &remove_gen_stmt, NULL); + sqlite3_stmt *get_user_table_id_stmt; + sql::prepare_v2(db, get_user_table_id, -1, &get_user_table_id_stmt, NULL); + + sqlite3_stmt *rem_like_w_user_table_id_stmt; + sql::prepare_v2(db, rem_like_w_user_table_id, -1, &rem_like_w_user_table_id_stmt, NULL); + + sqlite3_stmt *rem_user_table_id_stmt; + sql::prepare_v2(db, rem_user_table_id, -1, &rem_user_table_id_stmt, NULL); sqlite3_stmt *set_checked_stmt; sql::prepare_v2(db, set_checked, -1, &set_checked_stmt, NULL); @@ -46,7 +52,7 @@ void checker() std::this_thread::sleep_for(60s); continue; } - + printf("Start Check\n"); DnaManagerData data; data.id = user_id; data.randSeed = mrand::getState(data.id); @@ -76,16 +82,17 @@ void checker() if ((unit.index != pos) || (hash != cal_hash)) { found_err = true; - sql::bind_int64(remove_gen_stmt, 1, data.id); - sql::bind_int64(remove_gen_stmt, 2, data.generation); - sql::step(remove_gen_stmt); - sql::reset(remove_gen_stmt); break; } unit.liked = (Liked)liked; new_gen = DnaManager::like(unit, &data); } + if (!new_gen) + { + found_err = true; + } + if (!found_err) { sql::bind_int64(set_checked_stmt, 1, data.id); @@ -93,20 +100,37 @@ void checker() sql::step(set_checked_stmt); sql::reset(set_checked_stmt); } - if (!new_gen) - { - found_err = true; - sql::bind_int64(remove_gen_stmt, 1, data.id); - sql::bind_int64(remove_gen_stmt, 2, data.generation); - sql::step(remove_gen_stmt); - sql::reset(remove_gen_stmt); - } else + { + sql::bind_int64(get_user_table_id_stmt, 1, data.id); + sql::bind_int64(get_user_table_id_stmt, 2, data.generation); + int64_t user_table_id = 0; + if (sql::step(get_user_table_id_stmt) != SQL_DONE) + { + int type = sql::column_type(get_user_table_id_stmt, 0); + if (type != SQL_NULL) + { + user_table_id = sql::column_int64(get_user_table_id_stmt, 0); + } + } + sql::reset(get_user_table_id_stmt); + + sql::bind_int64(rem_like_w_user_table_id_stmt, 1, user_table_id); + sql::step(rem_like_w_user_table_id_stmt); + sql::reset(rem_like_w_user_table_id_stmt); + + sql::bind_int64(rem_user_table_id_stmt, 1, user_table_id); + sql::step(rem_user_table_id_stmt); + sql::reset(rem_user_table_id_stmt); + } + + if (new_gen) { DnaManager::newGen(&data); } sql::reset(get_gen_stmt); } + printf("End Check\n"); } } \ No newline at end of file diff --git a/server/src/server.cpp b/server/src/server.cpp index 0d547c5..0ea2825 100644 --- a/server/src/server.cpp +++ b/server/src/server.cpp @@ -38,7 +38,7 @@ void call(int sock, sockaddr_in newSocketInfo) bool ok = true; sqlite3 *db; - sqlite3_stmt *stmt; + sqlite3_stmt *max_gen_stmt; int rc = sql::open(DB_NAME, &db); if (rc) @@ -47,23 +47,27 @@ void call(int sock, sockaddr_in newSocketInfo) ok = false; } - sql::prepare_v2(db, max_gen, -1, &stmt, NULL); - sql::bind_int64(stmt, 1, id); + sql::prepare_v2(db, max_gen, -1, &max_gen_stmt, NULL); + sql::bind_int64(max_gen_stmt, 1, id); int64_t gen = 0; - while (sql::step(stmt) != SQL_DONE) + while (sql::step(max_gen_stmt) != SQL_DONE) { - int num_cols = sql::column_count(stmt); + int num_cols = sql::column_count(max_gen_stmt); - int type = sql::column_type(stmt, 0); + int type = sql::column_type(max_gen_stmt, 0); if (type == SQL_NULL) break; - gen = sql::column_int64(stmt, 0); + gen = sql::column_int64(max_gen_stmt, 0); gen++; } - sql::finalize(stmt); + sql::finalize(max_gen_stmt); - sql::prepare_v2(db, insert_data, -1, &stmt, NULL); + sqlite3_stmt *insert_liked_stmt; + sql::prepare_v2(db, insert_like_data, -1, &insert_liked_stmt, NULL); + + sqlite3_stmt *insert_user_stmt; + sql::prepare_v2(db, insert_user_data, -1, &insert_user_stmt, NULL); while (ok) { @@ -83,21 +87,28 @@ void call(int sock, sockaddr_in newSocketInfo) TcpSocket::recvt(sock, list.data(), NUM_PER_GEN * sizeof(NetUnit)); + sql::bind_int64(insert_user_stmt, 1, id); + sql::bind_int64(insert_user_stmt, 2, gen); + sql::step(insert_user_stmt); + sql::reset(insert_user_stmt); + + int64_t user_table_id = sql::last_insert_rowid(db); + for (size_t i = 0; i < list.size(); i++) { - sql::bind_int64(stmt, 1, id); - sql::bind_int64(stmt, 2, gen); - sql::bind_int64(stmt, 3, list[i].hash); - sql::bind_int64(stmt, 4, list[i].index); - sql::bind_int64(stmt, 5, list[i].liked); - sql::step(stmt); - sql::reset(stmt); + sql::bind_int64(insert_liked_stmt, 1, user_table_id); + sql::bind_int64(insert_liked_stmt, 2, list[i].hash); + sql::bind_int64(insert_liked_stmt, 3, list[i].index); + sql::bind_int64(insert_liked_stmt, 4, list[i].liked); + sql::step(insert_liked_stmt); + sql::reset(insert_liked_stmt); } gen++; } - sql::finalize(stmt); + sql::finalize(insert_user_stmt); + sql::finalize(insert_liked_stmt); sql::close(db); printf("del\n"); diff --git a/server/src/sql.cpp b/server/src/sql.cpp index 7acf906..f4c5f19 100644 --- a/server/src/sql.cpp +++ b/server/src/sql.cpp @@ -26,8 +26,7 @@ void sql::init() } /* Execute SQL statement */ - rc = sqlite3_exec(db, create_table, nullptr, 0, &zErrMsg); - + rc = sqlite3_exec(db, create_like_table, nullptr, 0, &zErrMsg); if (rc != SQLITE_OK) { fprintf(stderr, "SQL error: %s\n", zErrMsg); @@ -35,12 +34,10 @@ void sql::init() } else { - fprintf(stdout, "Table created successfully\n"); + fprintf(stdout, "like_table created successfully\n"); } - /* Execute SQL statement */ - rc = sqlite3_exec(db, create_index, nullptr, 0, &zErrMsg); - + rc = sqlite3_exec(db, create_user_table, nullptr, 0, &zErrMsg); if (rc != SQLITE_OK) { fprintf(stderr, "SQL error: %s\n", zErrMsg); @@ -48,7 +45,7 @@ void sql::init() } else { - fprintf(stdout, "Index created successfully\n"); + fprintf(stdout, "user_table created successfully\n"); } sqlite3_close(db); @@ -105,4 +102,8 @@ namespace sql { return sqlite3_errmsg(db); } + int64_t last_insert_rowid(sqlite3 *db) + { + return sqlite3_last_insert_rowid(db); + } } \ No newline at end of file