From 0cabb8ce8acd0e4e391ef9c3a040e94bee3fbc79 Mon Sep 17 00:00:00 2001 From: SJ Date: Mon, 28 Jan 2013 12:10:39 +0100 Subject: [PATCH] switching to prepared statements in attachment.c --- src/archive.c | 4 +- src/attachment.c | 117 +++++++++++++++++++++++++--------------------- src/config.h | 4 ++ src/defs.h | 4 ++ src/message.c | 2 +- src/piler.h | 6 +-- src/pilerexport.c | 7 +-- src/pilerget.c | 3 +- src/reindex.c | 2 +- 9 files changed, 84 insertions(+), 65 deletions(-) diff --git a/src/archive.c b/src/archive.c index 2cbadc06..e4117830 100644 --- a/src/archive.c +++ b/src/archive.c @@ -209,7 +209,7 @@ CLEANUP: } -int retrieve_email_from_archive(struct session_data *sdata, FILE *dest, struct __config *cfg){ +int retrieve_email_from_archive(struct session_data *sdata, struct __data *data, FILE *dest, struct __config *cfg){ int i, attachments; char *buffer=NULL, *saved_buffer, *p, filename[SMALLBUFSIZE], pointer[SMALLBUFSIZE]; struct ptr_array ptr_arr[MAX_ATTACHMENTS]; @@ -221,7 +221,7 @@ int retrieve_email_from_archive(struct session_data *sdata, FILE *dest, struct _ return 1; } - attachments = query_attachments(sdata, &ptr_arr[0], cfg); + attachments = query_attachments(sdata, data, &ptr_arr[0], cfg); if(attachments == -1){ printf("problem querying the attachment of %s\n", sdata->ttmpfile); diff --git a/src/attachment.c b/src/attachment.c index 3b334e5d..31a1fc26 100644 --- a/src/attachment.c +++ b/src/attachment.c @@ -16,21 +16,15 @@ #include -int store_attachments(struct session_data *sdata, struct _state *state, struct __config *cfg){ +int store_attachments(struct session_data *sdata, struct _state *state, struct __data *data, struct __config *cfg){ uint64 id=0; int i, rc=1, found, affected_rows; - char s[SMALLBUFSIZE]; - MYSQL_RES *res; - MYSQL_ROW row; - - MYSQL_STMT *stmt; MYSQL_BIND bind[7]; unsigned long len[7]; - snprintf(s, sizeof(s)-1, "INSERT INTO %s (`piler_id`,`attachment_id`,`sig`,`name`,`type`,`size`,`ptr`) VALUES(?,?,?,?,?,?,?)", SQL_ATTACHMENT_TABLE); - - if(prepare_a_mysql_statement(sdata, &stmt, s) == ERR) return rc; + if(prepare_a_mysql_statement(sdata, &(data->stmt_insert_into_attachment_table), SQL_PREPARED_STMT_INSERT_INTO_ATTACHMENT_TABLE) == ERR) return rc; + if(prepare_a_mysql_statement(sdata, &(data->stmt_get_attachment_id_by_signature), SQL_PREPARED_STMT_GET_ATTACHMENT_ID_BY_SIGNATURE) == ERR) return rc; for(i=1; i<=state->n_attachments; i++){ @@ -39,22 +33,45 @@ int store_attachments(struct session_data *sdata, struct _state *state, struct _ if(state->attachments[i].size > 0){ - snprintf(s, sizeof(s)-1, "SELECT `id` FROM `%s` WHERE `sig`='%s'", SQL_ATTACHMENT_TABLE, state->attachments[i].digest); + memset(bind, 0, sizeof(bind)); - if(cfg->verbosity >= _LOG_DEBUG) syslog(LOG_PRIORITY, "%s: check for attachment sql: *%s*", sdata->ttmpfile, s); + bind[0].buffer_type = MYSQL_TYPE_STRING; + bind[0].buffer = state->attachments[i].digest; + bind[0].is_null = 0; + len[0] = strlen(state->attachments[i].digest); bind[0].length = &len[0]; - if(mysql_real_query(&(sdata->mysql), s, strlen(s)) == 0){ - res = mysql_store_result(&(sdata->mysql)); - if(res != NULL){ - row = mysql_fetch_row(res); - if(row){ - id = strtoull(row[0], NULL, 10); - found = 1; - } - mysql_free_result(res); - } + if(mysql_stmt_bind_param(data->stmt_get_attachment_id_by_signature, bind)){ + syslog(LOG_PRIORITY, "%s: %s.mysql_stmt_bind_param() error for get attachment id: %s", sdata->ttmpfile, SQL_ATTACHMENT_TABLE, mysql_stmt_error(data->stmt_get_attachment_id_by_signature)); + goto NOT_FOUND; } + if(mysql_stmt_execute(data->stmt_get_attachment_id_by_signature)){ + syslog(LOG_PRIORITY, "%s get attachment id execute error: *%s*", sdata->ttmpfile, mysql_error(&(sdata->mysql))); + goto NOT_FOUND; + } + + + memset(bind, 0, sizeof(bind)); + + bind[0].buffer_type = MYSQL_TYPE_LONGLONG; + bind[0].buffer = (char *)&id; + bind[0].is_null = 0; + bind[0].length = 0; + + if(mysql_stmt_bind_result(data->stmt_get_attachment_id_by_signature, bind)){ + syslog(LOG_PRIORITY, "%s: %s.mysql_stmt_bind_result() error: %s", sdata->ttmpfile, SQL_ATTACHMENT_TABLE, mysql_stmt_error(data->stmt_get_attachment_id_by_signature)); + goto NOT_FOUND; + } + + if(mysql_stmt_store_result(data->stmt_get_attachment_id_by_signature)){ + goto NOT_FOUND; + } + + if(!mysql_stmt_fetch(data->stmt_get_attachment_id_by_signature)){ + found = 1; + } + +NOT_FOUND: if(found == 0){ if(store_file(sdata, state->attachments[i].internalname, 0, 0, cfg) == 0){ @@ -102,18 +119,18 @@ int store_attachments(struct session_data *sdata, struct _state *state, struct _ bind[6].length = 0; - if(mysql_stmt_bind_param(stmt, bind)){ - syslog(LOG_PRIORITY, "%s: %s.mysql_stmt_bind_param() error: %s", sdata->ttmpfile, SQL_ATTACHMENT_TABLE, mysql_stmt_error(stmt)); + if(mysql_stmt_bind_param(data->stmt_insert_into_attachment_table, bind)){ + syslog(LOG_PRIORITY, "%s: %s.mysql_stmt_bind_param() error: %s", sdata->ttmpfile, SQL_ATTACHMENT_TABLE, mysql_stmt_error(data->stmt_insert_into_attachment_table)); goto CLOSE; } - if(mysql_stmt_execute(stmt)){ + if(mysql_stmt_execute(data->stmt_insert_into_attachment_table)){ syslog(LOG_PRIORITY, "%s attachment sql error: *%s*", sdata->ttmpfile, mysql_error(&(sdata->mysql))); goto CLOSE; } - affected_rows = mysql_stmt_affected_rows(stmt); + affected_rows = mysql_stmt_affected_rows(data->stmt_insert_into_attachment_table); if(affected_rows != 1){ syslog(LOG_PRIORITY, "%s attachment sql error: affected rows: %d", sdata->ttmpfile, affected_rows); goto CLOSE; @@ -129,24 +146,21 @@ int store_attachments(struct session_data *sdata, struct _state *state, struct _ rc = 0; CLOSE: - mysql_stmt_close(stmt); + mysql_stmt_close(data->stmt_insert_into_attachment_table); + mysql_stmt_close(data->stmt_get_attachment_id_by_signature); return rc; } -int query_attachment_pointers(struct session_data *sdata, uint64 ptr, char *piler_id, int *id, struct __config *cfg){ +int query_attachment_pointers(struct session_data *sdata, struct __data *data, uint64 ptr, char *piler_id, int *id, struct __config *cfg){ int rc=0; - char s[SMALLBUFSIZE]; - MYSQL_STMT *stmt; MYSQL_BIND bind[2]; my_bool is_null[2]; unsigned long len=0; - snprintf(s, SMALLBUFSIZE-1, "SELECT `piler_id`, `attachment_id` FROM %s WHERE id=?", SQL_ATTACHMENT_TABLE); - - if(prepare_a_mysql_statement(sdata, &stmt, s) == ERR) goto ENDE; + if(prepare_a_mysql_statement(sdata, &(data->stmt_get_attachment_pointer), SQL_PREPARED_STMT_GET_ATTACHMENT_POINTER) == ERR) goto ENDE; memset(bind, 0, sizeof(bind)); @@ -156,12 +170,12 @@ int query_attachment_pointers(struct session_data *sdata, uint64 ptr, char *pile len = sizeof(uint64); bind[0].length = &len; - if(mysql_stmt_bind_param(stmt, bind)){ + if(mysql_stmt_bind_param(data->stmt_get_attachment_pointer, bind)){ goto CLOSE; } - if(mysql_stmt_execute(stmt)){ + if(mysql_stmt_execute(data->stmt_get_attachment_pointer)){ goto CLOSE; } @@ -180,23 +194,23 @@ int query_attachment_pointers(struct session_data *sdata, uint64 ptr, char *pile bind[1].length = 0; - if(mysql_stmt_bind_result(stmt, bind)){ + if(mysql_stmt_bind_result(data->stmt_get_attachment_pointer, bind)){ goto CLOSE; } - if(mysql_stmt_store_result(stmt)){ + if(mysql_stmt_store_result(data->stmt_get_attachment_pointer)){ goto CLOSE; } - if(!mysql_stmt_fetch(stmt)){ + if(!mysql_stmt_fetch(data->stmt_get_attachment_pointer)){ if(is_null[0] == 0){ rc = 1; } } CLOSE: - mysql_stmt_close(stmt); + mysql_stmt_close(data->stmt_get_attachment_pointer); ENDE: @@ -204,11 +218,9 @@ ENDE: } -int query_attachments(struct session_data *sdata, struct ptr_array *ptr_arr, struct __config *cfg){ +int query_attachments(struct session_data *sdata, struct __data *data, struct ptr_array *ptr_arr, struct __config *cfg){ int i, rc, id, attachments=0; uint64 ptr; - char s[SMALLBUFSIZE]; - MYSQL_STMT *stmt; MYSQL_BIND bind[2]; my_bool is_null[2]; unsigned long len=0; @@ -216,10 +228,7 @@ int query_attachments(struct session_data *sdata, struct ptr_array *ptr_arr, str for(i=0; istmt_query_attachment), SQL_PREPARED_STMT_QUERY_ATTACHMENT) == ERR) goto ENDE; memset(bind, 0, sizeof(bind)); @@ -229,12 +238,12 @@ int query_attachments(struct session_data *sdata, struct ptr_array *ptr_arr, str bind[0].is_null = 0; len = strlen(sdata->ttmpfile); bind[0].length = &len; - if(mysql_stmt_bind_param(stmt, bind)){ + if(mysql_stmt_bind_param(data->stmt_query_attachment, bind)){ goto CLOSE; } - if(mysql_stmt_execute(stmt)){ + if(mysql_stmt_execute(data->stmt_query_attachment)){ goto CLOSE; } @@ -253,23 +262,23 @@ int query_attachments(struct session_data *sdata, struct ptr_array *ptr_arr, str - if(mysql_stmt_bind_result(stmt, bind)){ - syslog(LOG_PRIORITY, "%s: %s.mysql_stmt_bind_result() error: %s", sdata->ttmpfile, SQL_METADATA_TABLE, mysql_stmt_error(stmt)); + if(mysql_stmt_bind_result(data->stmt_query_attachment, bind)){ + syslog(LOG_PRIORITY, "%s: %s.mysql_stmt_bind_result() error: %s", sdata->ttmpfile, SQL_METADATA_TABLE, mysql_stmt_error(data->stmt_query_attachment)); goto CLOSE; } - if(mysql_stmt_store_result(stmt)){ - syslog(LOG_PRIORITY, "%s: %s.mysql_stmt_store_result() error: %s", sdata->ttmpfile, SQL_METADATA_TABLE, mysql_stmt_error(stmt)); + if(mysql_stmt_store_result(data->stmt_query_attachment)){ + syslog(LOG_PRIORITY, "%s: %s.mysql_stmt_store_result() error: %s", sdata->ttmpfile, SQL_METADATA_TABLE, mysql_stmt_error(data->stmt_query_attachment)); goto CLOSE; } - while(!mysql_stmt_fetch(stmt)){ + while(!mysql_stmt_fetch(data->stmt_query_attachment)){ if(id > 0 && id < MAX_ATTACHMENTS){ if(ptr > 0){ ptr_arr[id].ptr = ptr; - rc = query_attachment_pointers(sdata, ptr, &(ptr_arr[id].piler_id[0]), &(ptr_arr[id].attachment_id), cfg); + rc = query_attachment_pointers(sdata, data, ptr, &(ptr_arr[id].piler_id[0]), &(ptr_arr[id].attachment_id), cfg); if(!rc){ attachments = -1; goto CLOSE; @@ -285,7 +294,7 @@ int query_attachments(struct session_data *sdata, struct ptr_array *ptr_arr, str } CLOSE: - mysql_stmt_close(stmt); + mysql_stmt_close(data->stmt_query_attachment); ENDE: diff --git a/src/config.h b/src/config.h index b6fe90f7..18e60a96 100644 --- a/src/config.h +++ b/src/config.h @@ -91,6 +91,10 @@ #define SQL_PREPARED_STMT_INSERT_INTO_RCPT_TABLE "INSERT INTO " SQL_RECIPIENT_TABLE " (`id`,`to`,`todomain`) VALUES(?,?,?)" #define SQL_PREPARED_STMT_INSERT_INTO_SPHINX_TABLE "INSERT INTO " SQL_SPHINX_TABLE " (`id`, `from`, `to`, `fromdomain`, `todomain`, `subject`, `body`, `arrived`, `sent`, `size`, `direction`, `folder`, `attachments`, `attachment_types`) values(?,?,?,?,?,?,?,?,?,?,?,?,?,?)" #define SQL_PREPARED_STMT_INSERT_INTO_META_TABLE "INSERT INTO " SQL_METADATA_TABLE " (`from`,`fromdomain`,`subject`,`spam`,`arrived`,`sent`,`retained`,`size`,`hlen`,`direction`,`attachments`,`piler_id`,`message_id`,`reference`,`digest`,`bodydigest`,`vcode`) VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)" +#define SQL_PREPARED_STMT_INSERT_INTO_ATTACHMENT_TABLE "INSERT INTO " SQL_ATTACHMENT_TABLE " (`piler_id`,`attachment_id`,`sig`,`name`,`type`,`size`,`ptr`) VALUES(?,?,?,?,?,?,?)" +#define SQL_PREPARED_STMT_GET_ATTACHMENT_ID_BY_SIGNATURE "SELECT `id` FROM `" SQL_ATTACHMENT_TABLE "` WHERE `sig`=?" +#define SQL_PREPARED_STMT_GET_ATTACHMENT_POINTER "SELECT `piler_id`, `attachment_id` FROM " SQL_ATTACHMENT_TABLE " WHERE id=?" +#define SQL_PREPARED_STMT_QUERY_ATTACHMENT "SELECT `attachment_id`, `ptr` FROM " SQL_ATTACHMENT_TABLE " WHERE piler_id=? ORDER BY attachment_id ASC" /* Error codes */ diff --git a/src/defs.h b/src/defs.h index 1b0a3c08..cccf210f 100644 --- a/src/defs.h +++ b/src/defs.h @@ -251,6 +251,10 @@ struct __data { MYSQL_STMT *stmt_insert_into_rcpt_table; MYSQL_STMT *stmt_insert_into_sphinx_table; MYSQL_STMT *stmt_insert_into_meta_table; + MYSQL_STMT *stmt_insert_into_attachment_table; + MYSQL_STMT *stmt_get_attachment_id_by_signature; + MYSQL_STMT *stmt_get_attachment_pointer; + MYSQL_STMT *stmt_query_attachment; #endif #ifdef HAVE_TRE diff --git a/src/message.c b/src/message.c index 8d2ba671..f6a8dde6 100644 --- a/src/message.c +++ b/src/message.c @@ -456,7 +456,7 @@ int process_message(struct session_data *sdata, struct _state *state, struct __d /* store base64 encoded file attachments */ if(state->n_attachments > 0){ - rc = store_attachments(sdata, state, cfg); + rc = store_attachments(sdata, state, data, cfg); for(i=1; i<=state->n_attachments; i++){ unlink(state->attachments[i].internalname); diff --git a/src/piler.h b/src/piler.h index 236e7355..7ca72e54 100644 --- a/src/piler.h +++ b/src/piler.h @@ -39,8 +39,8 @@ void remove_stripped_attachments(struct _state *state); int process_message(struct session_data *sdata, struct _state *state, struct __data *data, struct __config *cfg); int store_file(struct session_data *sdata, char *filename, int startpos, int len, struct __config *cfg); int remove_stored_message_files(struct session_data *sdata, struct _state *state, struct __config *cfg); -int store_attachments(struct session_data *sdata, struct _state *state, struct __config *cfg); -int query_attachments(struct session_data *sdata, struct ptr_array *ptr_arr, struct __config *cfg); +int store_attachments(struct session_data *sdata, struct _state *state, struct __data *data, struct __config *cfg); +int query_attachments(struct session_data *sdata, struct __data *data, struct ptr_array *ptr_arr, struct __config *cfg); struct __config read_config(char *configfile); @@ -48,7 +48,7 @@ void check_and_create_directories(struct __config *cfg, uid_t uid, gid_t gid); void update_counters(struct session_data *sdata, struct __data *data, struct __counters *counters, struct __config *cfg); -int retrieve_email_from_archive(struct session_data *sdata, FILE *dest, struct __config *cfg); +int retrieve_email_from_archive(struct session_data *sdata, struct __data *data, FILE *dest, struct __config *cfg); int prepare_a_mysql_statement(struct session_data *sdata, MYSQL_STMT **stmt, char *s); diff --git a/src/pilerexport.c b/src/pilerexport.c index 196a72b1..12786a0e 100644 --- a/src/pilerexport.c +++ b/src/pilerexport.c @@ -135,7 +135,7 @@ int append_string_to_buffer(char **buffer, char *str){ } -int export_emails_matching_to_query(struct session_data *sdata, char *s, struct __config *cfg){ +int export_emails_matching_to_query(struct session_data *sdata, struct __data *data, char *s, struct __config *cfg){ MYSQL_RES *res; MYSQL_ROW row; FILE *f; @@ -164,7 +164,7 @@ int export_emails_matching_to_query(struct session_data *sdata, char *s, struct f = fopen(filename, "w"); if(f){ - rc = retrieve_email_from_archive(sdata, f, cfg); + rc = retrieve_email_from_archive(sdata, data, f, cfg); fclose(f); n++; @@ -208,6 +208,7 @@ int main(int argc, char **argv){ char *to=NULL, *from=NULL; char s[SMALLBUFSIZE]; struct session_data sdata; + struct __data data; struct __config cfg; @@ -413,7 +414,7 @@ int main(int argc, char **argv){ mysql_real_query(&(sdata.mysql), "SET CHARACTER SET utf8", strlen("SET CHARACTER SET utf8")); - rc = export_emails_matching_to_query(&sdata, query, &cfg); + rc = export_emails_matching_to_query(&sdata, &data, query, &cfg); free(query); diff --git a/src/pilerget.c b/src/pilerget.c index 52aa47a4..af885d3d 100644 --- a/src/pilerget.c +++ b/src/pilerget.c @@ -19,6 +19,7 @@ int main(int argc, char **argv){ int readkey=1; struct session_data sdata; + struct __data data; struct __config cfg; @@ -52,7 +53,7 @@ int main(int argc, char **argv){ snprintf(sdata.ttmpfile, SMALLBUFSIZE-1, "%s", argv[1]); snprintf(sdata.filename, SMALLBUFSIZE-1, "%s", sdata.ttmpfile); - retrieve_email_from_archive(&sdata, stdout, &cfg); + retrieve_email_from_archive(&sdata, &data, stdout, &cfg); mysql_close(&(sdata.mysql)); diff --git a/src/reindex.c b/src/reindex.c index 4e8f20ff..858ebcc8 100644 --- a/src/reindex.c +++ b/src/reindex.c @@ -95,7 +95,7 @@ uint64 retrieve_email_by_metadata_id(struct session_data *sdata, struct __data * f = fopen(filename, "w"); if(f){ - rc = retrieve_email_from_archive(sdata, f, cfg); + rc = retrieve_email_from_archive(sdata, data, f, cfg); fclose(f); if(rc){