Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #define BUFF_SIZE 1024
- extern void parseInput();
- PGconn *conn = NULL;
- static bool checkConn(PGconn *conn) {
- if (!conn || PQstatus(conn) == CONNECTION_BAD) {
- fprintf(stderr, "Connection to server failed: %s\n" ,
- PQerrorMessage(conn));
- PQfinish(conn);
- return false;
- }
- return true;
- }
- static bool checkResCmdOK(PGresult *res) {
- if(!res || PQresultStatus(res) != PGRES_COMMAND_OK) {
- fprintf(stderr, "Error executing query: %s\n",
- PQresultErrorMessage(res));
- PQclear(res);
- return false;
- }
- return true;
- }
- static bool checkResTupOK(PGresult *res) {
- if(!res || PQresultStatus(res) != PGRES_TUPLES_OK) {
- fprintf(stderr, "Error executing query: %s\n",
- PQresultErrorMessage(res));
- PQclear(res);
- return false;
- }
- return true;
- }
- int main() {
- char connect_param[BUFF_SIZE];
- sprintf(connect_param, "host=csl2.cs.technion.ac.il dbname=%s user=%s password=%s", USERNAME, USERNAME, PASSWORD);
- conn = PQconnectdb(connect_param);
- if(!checkConn(conn)) return 1;
- parseInput();
- PQfinish(conn);
- return 0;
- }
- void* addUser (const char* name) {
- PGresult *res = NULL;
- char cmd[BUFF_SIZE] = { 0 };
- // add max user
- sprintf(cmd, "INSERT INTO users SELECT COALESCE((SELECT MAX(id) from users) + 1, 0) ,'%s' RETURNING id", name);
- res = PQexec(conn, cmd);
- if(!checkResTupOK(res)) return NULL;
- // print result
- printf(ADD_USER, PQgetvalue(res,0,0));
- PQclear(res);
- return (void*)1;
- }
- void* addUserMin (const char* name) {
- PGresult *res = NULL;
- char cmd[BUFF_SIZE] = { 0 };
- int i = 0;
- // add min user
- sprintf(cmd, "INSERT INTO users SELECT COALESCE((SELECT MIN(id) FROM users WHERE id+1 NOT IN (SELECT id FROM users))+1,0), '%s'", name);
- res = PQexec(conn, cmd);
- if(!checkResCmdOK(res)) return NULL;
- PQclear(res);
- // query db to get all users with 'name'
- sprintf(cmd, "SELECT id, name FROM users WHERE name = '%s' ORDER BY id", name);
- res = PQexec(conn, cmd);
- if(!checkResTupOK(res)) return NULL;
- // print result
- printf(USER_HEADER);
- for(; i < PQntuples(res); i++){
- printf(USER_RESULT, PQgetvalue(res,i,0), PQgetvalue(res,i,1));
- }
- PQclear(res);
- return (void*)1;
- }
- void* removeUser (const char* id) {
- PGresult *res = NULL;
- char cmd[BUFF_SIZE] = { 0 };
- // query the DB if the user_id exists
- sprintf(cmd, "SELECT id FROM users WHERE id = %s", id);
- res = PQexec(conn, cmd);
- if(!checkResTupOK(res)) return NULL;
- if(PQntuples(res) == 0) {
- printf(ILL_PARAMS);
- PQclear(res);
- return NULL;
- }
- PQclear(res);
- // remove the user id from the users
- sprintf(cmd, "DELETE FROM users WHERE id = %s", id);
- res = PQexec(conn, cmd);
- if(!checkResCmdOK(res)) return NULL;
- PQclear(res);
- // remove users photos
- sprintf(cmd, "DELETE FROM photos WHERE user_id = %s", id);
- res = PQexec(conn, cmd);
- if(!checkResCmdOK(res)) return NULL;
- PQclear(res);
- // remove users tags
- sprintf(cmd, "DELETE FROM tags WHERE user_id = %s", id);
- res = PQexec(conn, cmd);
- if(!checkResCmdOK(res)) return NULL;
- PQclear(res);
- return (void*)1;
- }
- void* addPhoto (const char* user_id, const char* photo_id) {
- PGresult *res = NULL;
- char cmd[BUFF_SIZE] = { 0 };
- // query the DB if the user_id exists
- sprintf(cmd, "SELECT id FROM users WHERE id = %s", user_id);
- res = PQexec(conn, cmd);
- if(!checkResTupOK(res)) return NULL;
- if(PQntuples(res) == 0) {
- printf(ILL_PARAMS);
- PQclear(res);
- return NULL;
- }
- PQclear(res);
- // query the DB if the photo_id already exists
- sprintf(cmd, "SELECT * FROM photos WHERE id = %s AND user_id = %s", photo_id, user_id);
- res = PQexec(conn, cmd);
- if(!checkResTupOK(res)) return NULL;
- if(PQntuples(res) != 0) {
- printf(EXISTING_RECORD);
- PQclear(res);
- return NULL;
- }
- PQclear(res);
- // add the photo with the requested photo_id to the user_id
- sprintf(cmd, "INSERT INTO photos SELECT %s, %s", photo_id, user_id);
- res = PQexec(conn, cmd);
- if(!checkResCmdOK(res)) return NULL;
- PQclear(res);
- return (void*)1;
- }
- void* tagPhoto (const char* user_id, const char* photo_id, const char* info) {
- PGresult *res = NULL;
- char cmd[BUFF_SIZE] = { 0 };
- // query the DB if the user_id exists
- sprintf(cmd, "SELECT id FROM users WHERE id = %s", user_id);
- res = PQexec(conn, cmd);
- if(!checkResTupOK(res)) return NULL;
- if(PQntuples(res) == 0) {
- printf(ILL_PARAMS);
- PQclear(res);
- return NULL;
- }
- PQclear(res);
- // query the DB if the exact tag already exists
- sprintf(cmd, "SELECT * FROM tags WHERE photo_id = %s AND user_id = %s AND info = '%s'", photo_id, user_id, info);
- res = PQexec(conn, cmd);
- if(!checkResTupOK(res)) return NULL;
- if(PQntuples(res) != 0) {
- printf(EXISTING_RECORD);
- PQclear(res);
- return NULL;
- }
- PQclear(res);
- // add the photo with the requested photo_id to the user_id
- sprintf(cmd, "INSERT INTO tags SELECT %s, %s, '%s'", photo_id, user_id, info);
- res = PQexec(conn, cmd);
- if(!checkResCmdOK(res)) return NULL;
- PQclear(res);
- return (void*)1;
- }
- void* photosTags () {
- PGresult *res = NULL;
- char cmd[BUFF_SIZE] = { 0 };
- int i = 0;
- // query the DB for number of tags for each photo
- sprintf(cmd, "SELECT photos.user_id, id, count(info) FROM photos LEFT OUTER JOIN tags ON photos.id = tags.photo_id AND photos.user_id = tags.user_id GROUP BY id, photos.user_id ORDER BY count(info) DESC, photos.user_id ASC, id ASC");
- res = PQexec(conn, cmd);
- if(!checkResTupOK(res)) return NULL;
- if(PQntuples(res) == 0) {
- printf(EMPTY);
- PQclear(res);
- return NULL;
- }
- // print the appropriate output
- printf(PHOTOS_HEADER);
- for(; i < PQntuples(res); i++){
- printf(PHOTOS_RESULT, PQgetvalue(res,i,0), PQgetvalue(res,i,1), PQgetvalue(res,i,2));
- }
- PQclear(res);
- return (void*)1;
- }
- void* search (const char* word) {
- PGresult *res = NULL;
- char cmd[BUFF_SIZE] = { 0 };
- int i = 0;
- // query the DB for number of tags for each photo that exists in photos containing the string word
- sprintf(cmd, "SELECT photos.user_id, photos.id, count(tags) FROM photos LEFT OUTER JOIN tags ON photos.id = tags.photo_id AND photos.user_id = tags.user_id WHERE info LIKE '%%%s%%' GROUP BY photos.id, photos.user_id ORDER BY count(tags) DESC ,photos.user_id ASC ,photos.id DESC", word);
- res = PQexec(conn, cmd);
- if(!checkResTupOK(res)) return NULL;
- if(PQntuples(res) == 0) {
- printf(EMPTY);
- PQclear(res);
- return NULL;
- }
- // print the appropriate output
- printf(PHOTOS_HEADER);
- for(; i < PQntuples(res); i++){
- printf(PHOTOS_RESULT, PQgetvalue(res,i,0), PQgetvalue(res,i,1), PQgetvalue(res,i,2));
- }
- PQclear(res);
- return (void*)1;
- }
- void* commonTags (const char* k) {
- PGresult *res = NULL;
- char cmd[BUFF_SIZE] = { 0 };
- int i = 0;
- // query the DB for common tags, at least k common tags
- sprintf(cmd, "SELECT info, count(photo_id) FROM tags GROUP BY info HAVING count(photo_id) >= %s ORDER BY count(photo_id) DESC ,info ASC", k);
- res = PQexec(conn, cmd);
- if(!checkResTupOK(res)) return NULL;
- if(PQntuples(res) == 0) {
- printf(EMPTY);
- PQclear(res);
- return NULL;
- }
- // print the appropriate output
- printf(COMMON_HEADER);
- for(; i < PQntuples(res); i++){
- printf(COMMON_LINE, PQgetvalue(res,i,0), PQgetvalue(res,i,1));
- }
- PQclear(res);
- return (void*)1;
- }
- void* mostCommonTags (const char* k) {
- PGresult *res = NULL;
- char cmd[BUFF_SIZE] = { 0 };
- int i = 0;
- // query the DB for common tags, max k tuples
- sprintf(cmd, "SELECT info, C FROM (SELECT count(*), MC1.info, MC1.C FROM (SELECT info, count(photo_id) AS C FROM tags GROUP BY info) AS MC1, (SELECT info, count(photo_id) AS C FROM tags GROUP BY info) AS MC2 WHERE MC1.C < MC2.C OR MC1.info >= MC2.info AND MC1.C = MC2.C GROUP BY MC1.info, MC1.C) AS SQ WHERE count <= %s ORDER BY C DESC, info ASC",k);
- res = PQexec(conn, cmd);
- if(!checkResTupOK(res)) return NULL;
- if(PQntuples(res) == 0) {
- printf(EMPTY);
- PQclear(res);
- return NULL;
- }
- // print the appropriate output
- printf(COMMON_HEADER);
- for(; i < PQntuples(res); i++){
- printf(COMMON_LINE, PQgetvalue(res,i,0), PQgetvalue(res,i,1));
- }
- PQclear(res);
- return (void*)1;
- }
- void* similarPhotos (const char* k, const char* j) {
- PGresult *res = NULL;
- char cmd[BUFF_SIZE] = { 0 };
- int i = 0;
- // query the DB for common tags, at least k common tags
- sprintf(cmd, "SELECT SQ2.t1_user_id, U1.name, SQ2.t1_photo_id FROM (SELECT t1_photo_id, t1_user_id, COUNT(t2_photo_id::text || t2_user_id::text) AS C2 FROM (SELECT DISTINCT T1.photo_id AS T1_photo_id, T1.user_id AS T1_user_id, T2.photo_id AS T2_photo_id, T2.user_id AS T2_user_id, COUNT(T2.info) FROM tags T1, tags T2 WHERE T1.info = T2.info AND T1.photo_id <> T2.photo_id OR T1.info = T2.info AND T1.user_id <> T2.user_id GROUP BY T1.photo_id, T1.user_id, T2.photo_id, T2.user_id HAVING COUNT(T2.info) >= %s) AS SQ GROUP BY t1_photo_id, t1_user_id HAVING COUNT(t2_photo_id::text || t2_user_id::text) >= %s) AS SQ2 LEFT OUTER JOIN users U1 ON SQ2.t1_user_id = U1.id ORDER BY t1_user_id ASC, t1_photo_id ASC;", j, k);
- res = PQexec(conn, cmd);
- if(!checkResTupOK(res)) return NULL;
- if(PQntuples(res) == 0) {
- printf(EMPTY);
- PQclear(res);
- return NULL;
- }
- // print the appropriate output
- printf(SIMILAR_HEADER);
- for(; i < PQntuples(res); i++){
- printf(SIMILAR_RESULT, PQgetvalue(res,i,0), PQgetvalue(res,i,1), PQgetvalue(res,i,2));
- }
- PQclear(res);
- return (void*)1;
- }
- void* autoPhotoOnTagOn () {
- PGresult *res = NULL;
- char cmd[BUFF_SIZE] = { 0 };
- // create function to add missing photos on tag insertion
- sprintf(cmd, " CREATE OR REPLACE FUNCTION add_missing_photos() \
- RETURNS TRIGGER AS $$ \
- BEGIN \
- IF((New.photo_id::text || NEW.user_id::text) NOT IN (SELECT (id::text || user_id::text) FROM photos)) THEN \
- INSERT INTO photos VALUES(NEW.photo_id, new.user_id); \
- END IF; \
- RETURN NEW; \
- END; \
- $$ LANGUAGE plpgsql;");
- res = PQexec(conn, cmd);
- if(!checkResCmdOK(res)) return NULL;
- PQclear(res);
- // create trigger to activate function
- sprintf(cmd, "CREATE TRIGGER tag_trigger BEFORE INSERT ON tags FOR EACH ROW EXECUTE PROCEDURE add_missing_photos();");
- res = PQexec(conn, cmd);
- if(!checkResCmdOK(res)) return NULL;
- PQclear(res);
- return (void*)1;
- }
- void* autoPhotoOnTagOFF () {
- PGresult *res = NULL;
- char cmd[BUFF_SIZE] = { 0 };
- // destroy trigger
- sprintf(cmd, "DROP TRIGGER tag_trigger ON tags;");
- res = PQexec(conn, cmd);
- if(!checkResCmdOK(res)) return NULL;
- PQclear(res);
- // destroy function
- sprintf(cmd, "DROP FUNCTION add_missing_photos();");
- res = PQexec(conn, cmd);
- if(!checkResCmdOK(res)) return NULL;
- PQclear(res);
- return (void*)1;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement