[Refdb-cvs] CVS: refdb/src refdbd.h.in,1.7.2.11,1.7.2.12 refdbd.c,1.74.2.17,1.74.2.18 refdbdref.c,1.
Status: Beta
Brought to you by:
mhoenicka
From: Markus H. <mho...@us...> - 2005-10-11 20:33:06
|
Update of /cvsroot/refdb/refdb/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv7815/src Modified Files: Tag: Release_0_9_5_stable refdbd.h.in refdbd.c refdbdref.c Log Message: added updatejo() Index: refdbd.h.in =================================================================== RCS file: /cvsroot/refdb/refdb/src/refdbd.h.in,v retrieving revision 1.7.2.11 retrieving revision 1.7.2.12 diff -u -U2 -r1.7.2.11 -r1.7.2.12 --- refdbd.h.in 21 Sep 2005 23:36:51 -0000 1.7.2.11 +++ refdbd.h.in 11 Oct 2005 20:32:55 -0000 1.7.2.12 @@ -134,4 +134,5 @@ int getnote(struct CLIENT_REQUEST* ptr_clrequest, struct bibinfo *ptr_biblio_info, int ref_format, int n_privatelist, char *cgi_url, struct ADDRESULT* ptr_addresult); int addlink(struct CLIENT_REQUEST* ptr_clrequest, char* set_owner, struct ADDRESULT* ptr_addresult, int n_remove); +int updatejo(struct CLIENT_REQUEST* ptr_clrequest, struct ADDRESULT* ptr_addresult); struct CLIENT_REQUEST* new_client_request(void); struct CLIENT_REQUEST* dup_client_request(struct CLIENT_REQUEST* ptr_clrequest); Index: refdbd.c =================================================================== RCS file: /cvsroot/refdb/refdb/src/refdbd.c,v retrieving revision 1.74.2.17 retrieving revision 1.74.2.18 diff -u -U2 -r1.74.2.17 -r1.74.2.18 --- refdbd.c 21 Sep 2005 23:35:17 -0000 1.74.2.17 +++ refdbd.c 11 Oct 2005 20:32:55 -0000 1.74.2.18 @@ -1573,6 +1573,4 @@ ptr_biblio_info->encoding = ptr_child_clrequest->db_encoding; -/* printf("child sleeps PID=%d\n", getpid()); */ -/* sleep(10); */ retval = getref(ptr_child_clrequest, ptr_biblio_info, ref_format, n_privatelist, pdfroot, cgi_url, ptr_addresult); @@ -1757,4 +1755,17 @@ } + /*********************************************** updatejo ****/ + else if (strcmp((ptr_child_clrequest->inargv)[0], "updatejo") == 0) { + retval = updatejo(ptr_child_clrequest, ptr_addresult); + + /* let the client know what happened */ + if (retval != 1) { + n_client_status = read_status(ptr_child_clrequest->fd); + send_status(ptr_child_clrequest->fd, 0, TERM_NO); + + sprintf(child_returnmsg, ULLSPEC" updated:"ULLSPEC" skipped:"ULLSPEC" failed\n", (unsigned long long)(ptr_addresult->success), (unsigned long long)(ptr_addresult->skipped), (unsigned long long)(ptr_addresult->failure)); + } + } + /*********************************************** adduser ****/ else if (strcmp((ptr_child_clrequest->inargv)[0], "adduser") == 0) { Index: refdbdref.c =================================================================== RCS file: /cvsroot/refdb/refdb/src/refdbdref.c,v retrieving revision 1.65.2.17 retrieving revision 1.65.2.18 diff -u -U2 -r1.65.2.17 -r1.65.2.18 --- refdbdref.c 7 Sep 2005 23:45:03 -0000 1.65.2.17 +++ refdbdref.c 11 Oct 2005 20:32:55 -0000 1.65.2.18 @@ -33,11 +33,4 @@ */ -/* ToDo: implement updatejo command. Could work like this: - use four parameters or arguments, like in - updatejo -a abbrev -f full -1 custabbrev1 -2 custabbrev2 - refdbd tries to match the data to an existing entry from left to right - and updates the other fields -*/ - #include <stdio.h> #include <unistd.h> @@ -86,4 +79,5 @@ static unsigned long long read_ris_data(struct CLIENT_REQUEST* ptr_clrequest, struct ADDRESULT* ptr_addresult, dbi_conn conn, dbi_conn conn_refdb, int replace_ref, int n_keep_id, const char* the_user, Lilid* ptr_sentinel, iconv_t conv_descriptor, int iconv_init_status); static int real_run_keyword_scan(struct CLIENT_REQUEST* ptr_clrequest, Lilid* ptr_sentinel, int mode, int* ptr_insert); +static int is_journal(dbi_conn conn, const char* field, const char* quoted_name); @@ -2005,4 +1999,411 @@ /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + updatejo(): implements the client command updatejo + + int updatejo returns 1 if failed, 0 if successful + + struct CLIENT_REQUEST* ptr_clrequest ptr to structure with client info + + struct ADDRESULT* addresult this structure will be filled in with the number + of (un-)successfully added/updated references + + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ +int updatejo(struct CLIENT_REQUEST* ptr_clrequest, struct ADDRESULT* ptr_addresult) { + dbi_conn conn; + dbi_result dbires; + dbi_driver driver; + char **inargv; /* tokens of the client request */ + int inargc; /* number of tokens of the client request */ + int inargcmax; /* maximum number of tokens of the client request */ + int len; + int result; + int mode; + int retval = 0; + int havefirst = 0; + int error = 0; /* codes: 0 = no error, 1 = out of memory, 2 = subselect failed */ + int syn_count = 0; /* counter for synonyms changed */ + unsigned long long n_id; + unsigned long long n_target_id; + size_t buffer_len; /* these are the allocated lengths of the buffers */ + size_t sql_command_len; + size_t return_msg_len; + char *return_msg; + char *sql_command; /* these are ptrs to the buffers and temporary ptrs */ + char *new_sql_command; + char *buffer; + char *new_buffer; + char *token; + char *newtoken; + char *stripped_token; + char *quoted_token; + char *eostring; + char journal_val[256] = ""; /* name of journal*/ + char journal_field[23] = ""; /* t_periodical field name of synonym */ + char field_buffer[10]; + char my_type[20]; + char assemble_buffer[2048]; + char jo[256] = ""; + char jf[256] = ""; + char j1[256] = ""; + char j2[256] = ""; + struct SQLTOKEN sqltoken; + struct lilimem sentinel; + Liliform *ptr_curr; + Liliform syn_sentinel; + + ptr_addresult->success = 0; + ptr_addresult->failure = 0; + ptr_addresult->updated = 0; + ptr_addresult->skipped = 0; + + sentinel.ptr_mem = NULL; + sentinel.ptr_next = NULL; + sentinel.varname[0] = '\0'; + + syn_sentinel.ptr_next = NULL; + syn_sentinel.name[0] = '\0'; + syn_sentinel.value = NULL; + + /* get buffer to analyze the request */ + inargc = 0; + inargcmax = 10; + inargv = malloc((size_t)inargcmax*sizeof(char*)); + if (inargv == NULL || insert_lilimem(&sentinel, (void**)&inargv, NULL)) { + send_status(ptr_clrequest->fd, 801, TERM_NO); + LOG_PRINT(LOG_CRIT, get_status_msg(801)); + return 1; + } + + /* get buffer to assemble the SQL queries */ + sql_command_len = 4096; + sql_command = malloc(sql_command_len); + + if (sql_command == NULL || insert_lilimem(&sentinel, (void**)&sql_command, NULL)) { + delete_all_lilimem(&sentinel); + send_status(ptr_clrequest->fd, 801, TERM_NO); + LOG_PRINT(LOG_CRIT, get_status_msg(801)); + return 1; + } + *sql_command = '\0'; /* start with an empty string */ + + /* get a buffer to hold tokens */ + buffer_len = 4096; + buffer = malloc(buffer_len); + + if (buffer == NULL || insert_lilimem(&sentinel, (void**)&buffer, NULL)) { + delete_all_lilimem(&sentinel); + send_status(ptr_clrequest->fd, 801, TERM_NO); + LOG_PRINT(LOG_CRIT, get_status_msg(801)); + return 1; + } + *buffer = '\0'; /* start with an empty string */ + + /* yet another buffer */ + return_msg_len = 4096; + return_msg = malloc(return_msg_len); + + if (return_msg == NULL || insert_lilimem(&sentinel, (void**)&return_msg, NULL)) { + delete_all_lilimem(&sentinel); + send_status(ptr_clrequest->fd, 801, TERM_NO); + LOG_PRINT(LOG_CRIT, get_status_msg(801)); + return 1; + } + *return_msg = '\0'; /* start with an empty string */ + + eostring = ptr_clrequest->argument + strlen(ptr_clrequest->argument); + + /* connect to the database */ + if ((conn = connect_to_db(ptr_clrequest, NULL, 0)) == NULL) { + send_status(ptr_clrequest->fd, 204, TERM_NO); + LOG_PRINT(LOG_WARNING, get_status_msg(204)); + delete_all_lilimem(&sentinel); + return 1; + } + + driver = dbi_conn_get_driver(conn); + + token = ptr_clrequest->argument; + newtoken = token; + + printf("%s\n", token); + + /* general strategy: scan the command string for items and add all of + them except the first to a linked list. Then walk through + the linked list to assemble the update query */ + + + /* loop as long as we find more tokens */ + while (newtoken != NULL) { + token = link_tokenize(newtoken, &sqltoken); + newtoken = sqltoken.next_token; +/* printf("token:%s<<newtoken:%s<<\n", token, newtoken); */ + + if (token != NULL) { + /* extract the token and save to a temporary string */ + if (sqltoken.length > buffer_len) { + new_buffer = (char*)realloc(buffer, (size_t)sqltoken.length); + if (new_buffer == NULL) { /* out of memory */ + error = 1; + break; + } + else { + buffer = new_buffer; + buffer_len = sqltoken.length; + } + } + strncpy(buffer, token, sqltoken.length); + buffer[sqltoken.length] ='\0'; + if (sqltoken.type == 4) { + /*----------------------------------------------------------------*/ + /* target fields */ + if (strncmp(token, ":JF:", 4) == 0 || /* journal full */ + strncmp(token, ":JO:", 4) == 0 || /* journal abbrev */ + strncmp(token, ":J1:", 4) == 0 || /* journal custabbrev1 */ + strncmp(token, ":J2:", 4) == 0) { /* journal custabbrev2 */ + + strcpy(field_buffer, buffer); + field_buffer[4] = '\0'; /* terminate string */ + + /* obtain the token after the '=' */ + token = link_tokenize(newtoken, &sqltoken); + newtoken = sqltoken.next_token; + if (token != NULL) { + strncpy(buffer, token, sqltoken.length); + buffer[sqltoken.length] ='\0'; /* terminate string */ + len = 0; + + /* terminate token at the next unprotected space */ + token = nstrtok(buffer, &len, " "); + if (token != NULL) { +/* printf("token went to: %s<<\n", token); */ + strncpy(buffer, token, sqltoken.length); + buffer[sqltoken.length] ='\0'; /* terminate string */ + len = 0; + token = nstrtok(buffer, &len, " "); + if (token != NULL) { + quoted_token = malloc(strlen(token)+1); + if (!quoted_token) { + error = 1; + break; + } + + stripped_token = strip_quote(token); + + unescape_chars(quoted_token, stripped_token, strlen(stripped_token)); + + +/* printf("quoted_token went to: %s<<\n", quoted_token); */ + + if (!havefirst) { + if (!strcmp(field_buffer, ":JF:")) { + strcpy(journal_field, "periodical_name"); + } + else if (!strcmp(field_buffer, ":JO:")) { + strcpy(journal_field, "periodical_abbrev"); + } + else if (!strcmp(field_buffer, ":J1:")) { + strcpy(journal_field, "periodical_custabbrev1"); + } + else { + strcpy(journal_field, "periodical_custabbrev2"); + } + + if (dbi_conn_quote_string(conn, "ed_token) == 0) { + error = 1; + break; + } + + strncpy(journal_val, quoted_token, 255); + journal_val[255] = '\0'; + /* printf("key:%s<<value:%s<<\n", journal_type, journal_val); */ + free(quoted_token); + + if (is_journal(conn, journal_field, journal_val) != 1) { + error = 2; + break; + } + havefirst++; + } + else { + if (insert_liliform(&syn_sentinel, field_buffer, quoted_token)) { + error = 1; + break; + } + } + } + } + } + } + else { + /* ignore unknown specifier */ + ptr_addresult->skipped++; + } + } /* if (sqltoken.type != 4) / else */ + } /* if (token != NULL) */ + } /* while (newtoken != NULL) */ + + if (error || !*journal_field || !*journal_val) { + if (error == 1) { + send_status(ptr_clrequest->fd, 801, TERM_NO); + LOG_PRINT(LOG_CRIT, get_status_msg(801)); + } + else { + send_status(ptr_clrequest->fd, 417, TERM_NO); + LOG_PRINT(LOG_INFO, get_status_msg(417)); + } + retval = 1; + goto Finish; + } + + /* loop over all synonyms. If the same synonym is specified more + than once, the last value prevails */ + ptr_curr = &syn_sentinel; + + while ((ptr_curr = get_next_liliform(ptr_curr)) != NULL) { + /* strcpy is sufficient as ptr_curr->value is already checked for length */ + quoted_token = mstrdup(ptr_curr->value); + if (!quoted_token) { + error = 1; + break; + } + if (dbi_conn_quote_string(conn, "ed_token) == 0) { + error = 1; + break; + } + + if (!strcmp(ptr_curr->name, ":JO:")) { + strcpy(jo, quoted_token); + free(ptr_curr->value); + } + else if (!strcmp(ptr_curr->name, ":JF:")) { + strcpy(jf, quoted_token); + free(ptr_curr->value); + } + else if (!strcmp(ptr_curr->name, ":J1:")) { + strcpy(j1, quoted_token); + free(ptr_curr->value); + } + else if (!strcmp(ptr_curr->name, ":J2:")) { + strcpy(j2, quoted_token); + free(ptr_curr->value); + } + free(quoted_token); + } + + if (error) { + send_status(ptr_clrequest->fd, 801, TERM_NO); + LOG_PRINT(LOG_CRIT, get_status_msg(801)); + retval = 1; + goto Finish; + } + + /* assemble query string */ + strcpy(sql_command, "UPDATE t_periodical SET "); + + if (*jf) { + sprintf(sql_command + strlen(sql_command), "periodical_name=%s, ", jf); + syn_count++; + sprintf(return_msg, "425:%s:%s\n", journal_val, jf); + } + + if (*jo) { + sprintf(sql_command + strlen(sql_command), "periodical_abbrev=%s, ", jo); + syn_count++; + sprintf(return_msg+strlen(return_msg), "425:%s:%s\n", journal_val, jo); + } + + if (*j1) { + sprintf(sql_command + strlen(sql_command), "periodical_custabbrev1=%s, ", j1); + syn_count++; + sprintf(return_msg+strlen(return_msg), "425:%s:%s\n", journal_val, j1); + } + + if (*j2) { + sprintf(sql_command + strlen(sql_command), "periodical_custabbrev2=%s, ", j2); + syn_count++; + sprintf(return_msg+strlen(return_msg), "425:%s:%s\n", journal_val, j2); + } + + /* remove trailing comma */ + sprintf(sql_command + strlen(sql_command) - 2, " WHERE %s=%s", journal_field, journal_val); + + LOG_PRINT(LOG_DEBUG, sql_command); + + dbires = dbi_conn_query(conn, sql_command); + + if (!dbires) { + error = 1; + goto Finish; + } + + ptr_addresult->success += syn_count; + + Finish: + if (ptr_addresult->success) { + /* database was changed, update meta info */ + update_meta(conn, ptr_clrequest); + } + + /* send back result message */ + if (!error) { + send_status(ptr_clrequest->fd, 0, TERM_NO); + } + else { + send_status(ptr_clrequest->fd, 260, TERM_NO); + } + + tiwrite(ptr_clrequest->fd, return_msg, TERM_YES); + + dbi_conn_close(conn); + delete_all_lilimem(&sentinel); + delete_all_liliform(&syn_sentinel); + + return retval; +} + + +/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + is_journal(): checks whether journal exists + + int is_journal returns 0 = not found, 1 = journal exists, -1: error + + dbi_conn conn connection to database + + const char* field field to check + + const char* quoted_name periodical name (properly escaped and quoted) + + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ +static int is_journal(dbi_conn conn, const char* field, const char* quoted_name) { + unsigned long long result; + char sql_command[512]; + dbi_result dbires; + + snprintf(sql_command, 512, "SELECT periodical_id FROM t_periodical WHERE %s=%s", field, quoted_name); + + LOG_PRINT(LOG_DEBUG, sql_command); + + dbires = dbi_conn_query(conn, sql_command); + + if (!dbires) { + LOG_PRINT(LOG_ERR, get_status_msg(234)); + return -1; + } + + result = dbi_result_get_numrows(dbires); + + if (!result) { + return 0; + } + else if (result == DBI_ROW_ERROR) { + LOG_PRINT(LOG_ERR, get_status_msg(234)); + return -1; + } + else { + return 1; + } +} + +/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ getref(): implements the client command getref |