static int _pgsql_jobcomp_check_tables(char *user) { int i = 0, job_found = 0; PGresult *result = NULL; char *query = xstrdup_printf("select tablename from pg_tables " "where tableowner='%s' " "and tablename !~ '^pg_+'", user); if(!(result = pgsql_db_query_ret(jobcomp_pgsql_db, query))) { xfree(query); return SLURM_ERROR; } xfree(query); for (i = 0; i < PQntuples(result); i++) { if(!job_found && !strcmp(jobcomp_table, PQgetvalue(result, i, 0))) job_found = 1; } PQclear(result); if(!job_found) if(pgsql_db_create_table(jobcomp_pgsql_db, "public", jobcomp_table, jobcomp_table_fields, ")") == SLURM_ERROR) return SLURM_ERROR; return SLURM_SUCCESS; }
extern int pgsql_insert_ret_id(PGconn *pgsql_db, char *sequence_name, char *query) { int new_id = 0; PGresult *result = NULL; slurm_mutex_lock(&pgsql_lock); if (pgsql_db_query(pgsql_db, query) != SLURM_ERROR) { char *new_query = xstrdup_printf( "select last_value from %s", sequence_name); if ((result = pgsql_db_query_ret(pgsql_db, new_query))) { new_id = atoi(PQgetvalue(result, 0, 0)); PQclear(result); } xfree(new_query); if (!new_id) { /* should have new id */ error("We should have gotten a new id: %s", PQerrorMessage(pgsql_db)); } } slurm_mutex_unlock(&pgsql_lock); return new_id; }
extern int pgsql_db_query(PGconn *pgsql_db, char *query) { PGresult *result = NULL; if (!pgsql_db) fatal("You haven't inited this storage yet."); if (!(result = pgsql_db_query_ret(pgsql_db, query))) return SLURM_ERROR; PQclear(result); return SLURM_SUCCESS; }
extern int pgsql_query_ret_id(PGconn *pgsql_db, char *query) { int new_id = 0; PGresult *result = NULL; slurm_mutex_lock(&pgsql_lock); result = pgsql_db_query_ret(pgsql_db, query); if (result) { new_id = atoi(PQgetvalue(result, 0, 0)); PQclear(result); } else { /* should have new id */ error("pgsql_query_ret_id() query failed: %s", PQerrorMessage(pgsql_db)); } slurm_mutex_unlock(&pgsql_lock); return new_id; }
/* * check_table - check account tables * IN db_conn: database connection * IN table: table name * IN fields: fields of the table * IN constraint: additional constraint of the table * RET: error code */ extern int check_table(PGconn *db_conn, char *schema, char *table, storage_field_t *fields, char *constraint) { DEF_VARS; char **tables = NULL; int i, num, rc = SLURM_SUCCESS; query = xstrdup_printf( "SELECT tablename FROM pg_tables WHERE schemaname='%s' AND " "tableowner='%s' AND tablename !~ '^pg_+' " "AND tablename !~ '^sql_+'", schema, PQuser(db_conn)); result = pgsql_db_query_ret(db_conn, query); xfree(query); if (!result) return SLURM_ERROR; num = PQntuples(result); tables = xmalloc(sizeof(char *) * (num + 1)); for (i = 0; i < num; i ++) tables[i] = xstrdup(PQgetvalue(result, i, 0)); tables[num] = NULL; PQclear(result); i = 0; while (tables[i] && strcmp(tables[i], table)) i ++; if (!tables[i]) { debug("as/pg: table %s.%s not found, create it", schema, table); rc = pgsql_db_create_table(db_conn, schema, table, fields, constraint); } else { rc = pgsql_db_make_table_current( db_conn, schema, table, fields); } for (i = 0; i < num; i ++) xfree(tables[i]); xfree(tables); return rc; }
extern List get_cluster_names(PGconn *db_conn) { PGresult *result = NULL; List ret_list = NULL; char *query = xstrdup_printf("SELECT name from %s WHERE deleted=0", cluster_table); result = pgsql_db_query_ret(db_conn, query); xfree(query); if (!result) return NULL; ret_list = list_create(slurm_destroy_char); FOR_EACH_ROW { if (! ISEMPTY(0)) list_append(ret_list, xstrdup(ROW(0))); } END_EACH_ROW; PQclear(result); return ret_list; }
extern List pgsql_jobcomp_process_get_jobs(slurmdb_job_cond_t *job_cond) { char *query = NULL; char *extra = NULL; char *tmp = NULL; char *selected_part = NULL; slurmdb_selected_step_t *selected_step = NULL; ListIterator itr = NULL; int set = 0; PGresult *result = NULL; int i; jobcomp_job_rec_t *job = NULL; char time_str[32]; time_t temp_time; List job_list = NULL; if (job_cond->step_list && list_count(job_cond->step_list)) { set = 0; xstrcat(extra, " where ("); itr = list_iterator_create(job_cond->step_list); while((selected_step = list_next(itr))) { if (set) xstrcat(extra, " || "); tmp = xstrdup_printf("jobid=%d", selected_step->jobid); xstrcat(extra, tmp); set = 1; xfree(tmp); } list_iterator_destroy(itr); xstrcat(extra, ")"); } if (job_cond->partition_list && list_count(job_cond->partition_list)) { set = 0; if (extra) xstrcat(extra, " && ("); else xstrcat(extra, " where ("); itr = list_iterator_create(job_cond->partition_list); while((selected_part = list_next(itr))) { if (set) xstrcat(extra, " || "); tmp = xstrdup_printf("partition='%s'", selected_part); xstrcat(extra, tmp); set = 1; xfree(tmp); } list_iterator_destroy(itr); xstrcat(extra, ")"); } i = 0; while(jobcomp_table_fields[i].name) { if (i) xstrcat(tmp, ", "); xstrcat(tmp, jobcomp_table_fields[i].name); i++; } query = xstrdup_printf("select %s from %s", tmp, jobcomp_table); xfree(tmp); if (extra) { xstrcat(query, extra); xfree(extra); } //info("query = %s", query); if (!(result = pgsql_db_query_ret(jobcomp_pgsql_db, query))) { xfree(query); return NULL; } xfree(query); job_list = list_create(jobcomp_destroy_job); for (i = 0; i < PQntuples(result); i++) { job = xmalloc(sizeof(jobcomp_job_rec_t)); if (PQgetvalue(result, i, JOBCOMP_REQ_JOBID)) job->jobid = atoi(PQgetvalue(result, i, JOBCOMP_REQ_JOBID)); job->partition = xstrdup(PQgetvalue(result, i, JOBCOMP_REQ_PARTITION)); temp_time = atoi(PQgetvalue(result, i, JOBCOMP_REQ_STARTTIME)); slurm_make_time_str(&temp_time, time_str, sizeof(time_str)); job->start_time = xstrdup(time_str); temp_time = atoi(PQgetvalue(result, i, JOBCOMP_REQ_ENDTIME)); slurm_make_time_str(&temp_time, time_str, sizeof(time_str)); job->end_time = xstrdup(time_str); if (PQgetvalue(result, i, JOBCOMP_REQ_UID)) job->uid = atoi(PQgetvalue(result, i, JOBCOMP_REQ_UID)); job->uid_name = xstrdup(PQgetvalue(result, i, JOBCOMP_REQ_USER_NAME)); if (PQgetvalue(result, i, JOBCOMP_REQ_GID)) job->gid = atoi(PQgetvalue(result, i, JOBCOMP_REQ_GID)); job->gid_name = xstrdup(PQgetvalue(result, i, JOBCOMP_REQ_GROUP_NAME)); job->jobname = xstrdup(PQgetvalue(result, i, JOBCOMP_REQ_NAME)); job->nodelist = xstrdup(PQgetvalue(result, i, JOBCOMP_REQ_NODELIST)); if (PQgetvalue(result, i, JOBCOMP_REQ_NODECNT)) job->node_cnt = atoi(PQgetvalue(result, i, JOBCOMP_REQ_NODECNT)); if (PQgetvalue(result, i, JOBCOMP_REQ_STATE)) { int j = atoi(PQgetvalue(result, i, JOBCOMP_REQ_STATE)); job->state = xstrdup(job_state_string(j)); } job->timelimit = xstrdup(PQgetvalue(result, i, JOBCOMP_REQ_TIMELIMIT)); if (PQgetvalue(result, i, JOBCOMP_REQ_MAXPROCS)) job->max_procs = atoi(PQgetvalue(result, i, JOBCOMP_REQ_MAXPROCS)); job->blockid = xstrdup(PQgetvalue(result, i, JOBCOMP_REQ_BLOCKID)); job->connection = xstrdup(PQgetvalue(result, i, JOBCOMP_REQ_CONNECTION)); job->reboot = xstrdup(PQgetvalue(result, i, JOBCOMP_REQ_REBOOT)); job->rotate = xstrdup(PQgetvalue(result, i, JOBCOMP_REQ_ROTATE)); job->geo = xstrdup(PQgetvalue(result, i, JOBCOMP_REQ_GEOMETRY)); job->bg_start_point = xstrdup(PQgetvalue(result, i, JOBCOMP_REQ_START)); list_append(job_list, job); } PQclear(result); return job_list; }
extern int pgsql_db_make_table_current(PGconn *pgsql_db, char *schema, char *table_name, storage_field_t *fields) { char *query = NULL, *opt_part = NULL, *temp_char = NULL; char *type = NULL; int not_null = 0; char *default_str = NULL; char* original_ptr = NULL; int i = 0; PGresult *result = NULL; List columns = NULL; ListIterator itr = NULL; char *col = NULL; DEF_TIMERS; query = xstrdup_printf("select column_name from " "information_schema.columns where " "table_name='%s' and table_schema='%s' ", table_name, schema); if (!(result = pgsql_db_query_ret(pgsql_db, query))) { xfree(query); return SLURM_ERROR; } xfree(query); columns = list_create(slurm_destroy_char); for (i = 0; i < PQntuples(result); i++) { col = xstrdup(PQgetvalue(result, i, 0)); //column_name list_append(columns, col); } PQclear(result); itr = list_iterator_create(columns); query = xstrdup_printf("alter table %s.%s", schema, table_name); START_TIMER; i=0; while (fields[i].name) { int found = 0; not_null = 0; if (!strcasecmp("serial", fields[i].options)) { i++; continue; } opt_part = xstrdup(fields[i].options); original_ptr = opt_part; opt_part = strtok_r(opt_part, " ", &temp_char); if (opt_part) { /* XXX: only one identifier supported */ type = xstrdup(opt_part); opt_part = strtok_r(NULL, " ", &temp_char); while (opt_part) { if (!strcasecmp("not", opt_part)) { opt_part = strtok_r(NULL, " ", &temp_char); if (!strcasecmp("null", opt_part)) { not_null = 1; } } else if (!strcasecmp("default", opt_part)){ opt_part = strtok_r(NULL, " ", &temp_char); default_str = xstrdup(opt_part); } opt_part = strtok_r(NULL, " ", &temp_char); } } else { type = xstrdup(fields[i].options); } xfree(original_ptr); list_iterator_reset(itr); while ((col = list_next(itr))) { if (!strcmp(col, fields[i].name)) { list_delete_item(itr); found = 1; break; } } temp_char = NULL; if (!found) { info("adding column %s", fields[i].name); if (default_str) xstrfmtcat(temp_char, " default %s", default_str); if (not_null) xstrcat(temp_char, " not null"); xstrfmtcat(query, " add %s %s", fields[i].name, type); if (temp_char) xstrcat(query, temp_char); xstrcat(query, ","); } else { if (default_str) xstrfmtcat(temp_char, " alter %s set default %s,", fields[i].name, default_str); else xstrfmtcat(temp_char, " alter %s drop default,", fields[i].name); if (not_null) xstrfmtcat(temp_char, " alter %s set not null,", fields[i].name); else xstrfmtcat(temp_char, " alter %s drop not null,", fields[i].name); xstrfmtcat(query, " alter %s type %s,%s", fields[i].name, type, temp_char); } xfree(temp_char); xfree(default_str); xfree(type); i++; } list_iterator_destroy(itr); list_destroy(columns); query[strlen(query)-1] = ';'; //debug4("pgsql db create/alter table:\n %s", query); if (pgsql_db_query(pgsql_db, query)) { xfree(query); return SLURM_ERROR; } xfree(query); END_TIMER2("make table current"); return SLURM_SUCCESS; }