mirror of https://github.com/BOINC/boinc.git
227 lines
5.5 KiB
C
227 lines
5.5 KiB
C
// The contents of this file are subject to the Mozilla Public License
|
|
// Version 1.0 (the "License"); you may not use this file except in
|
|
// compliance with the License. You may obtain a copy of the License at
|
|
// http://www.mozilla.org/MPL/
|
|
//
|
|
// Software distributed under the License is distributed on an "AS IS"
|
|
// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
|
|
// License for the specific language governing rights and limitations
|
|
// under the License.
|
|
//
|
|
// The Original Code is the Berkeley Open Infrastructure for Network Computing.
|
|
//
|
|
// The Initial Developer of the Original Code is the SETI@home project.
|
|
// Portions created by the SETI@home project are Copyright (C) 2002
|
|
// University of California at Berkeley. All Rights Reserved.
|
|
//
|
|
// Contributor(s):
|
|
//
|
|
|
|
// A collection of functions to facilitate MySQL access.
|
|
// Should be independent of the actual database
|
|
// (other than the assumption that ID is always field zero)
|
|
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
#include <assert.h>
|
|
|
|
#include "mysql.h"
|
|
#include "mysql_util.h"
|
|
|
|
extern char* table_name[];
|
|
extern void struct_to_str(void*, char*, int);
|
|
extern void row_to_struct(MYSQL_ROW&, void*, int);
|
|
|
|
static MYSQL *mp;
|
|
static MYSQL_RES *rp;
|
|
static MYSQL_ROW row;
|
|
|
|
#define MAX_QUERY_LEN 8192
|
|
|
|
int db_open(char* name) {
|
|
//assert(name!=NULL);
|
|
mp = mysql_init(0);
|
|
if (!mp) return -1;
|
|
mp = mysql_real_connect(mp, 0, 0, "", name, 0, 0, 0);
|
|
if (!mp) return -1;
|
|
return 0;
|
|
}
|
|
|
|
int db_close() {
|
|
mysql_close(mp);
|
|
return 0;
|
|
}
|
|
|
|
void db_print_error(char* p) {
|
|
assert(p!=NULL);
|
|
if (mp) {
|
|
printf("<br>%s: Database error: %s\n", p, mysql_error(mp));
|
|
}
|
|
}
|
|
|
|
// convert ' to \' in place
|
|
void escape(char* field) {
|
|
assert(field!=NULL);
|
|
char buf[MAX_QUERY_LEN];
|
|
char* q = buf, *p = field;
|
|
while (*p) {
|
|
if (*p == '\'') {
|
|
*q++ = '\'';
|
|
*q++ = '\'';
|
|
} else {
|
|
*q++ = *p;
|
|
}
|
|
p++;
|
|
}
|
|
*q = 0;
|
|
strcpy(field, buf);
|
|
}
|
|
|
|
void unescape(char* p) {
|
|
char* q;
|
|
assert(p!=NULL);
|
|
while (1) {
|
|
q = strstr(p, "\\'");
|
|
if (!q) break;
|
|
strcpy(q, q+1);
|
|
}
|
|
}
|
|
|
|
// assumes ID is first
|
|
static int* id(void* vp, int type) {
|
|
assert(vp!=NULL);
|
|
return (int*) vp;
|
|
}
|
|
|
|
int db_new(void* vp, int type) {
|
|
char buf[MAX_QUERY_LEN], sbuf[MAX_QUERY_LEN];
|
|
assert(vp!=NULL);
|
|
struct_to_str(vp, sbuf, type);
|
|
sprintf(buf, "insert into %s set %s", table_name[type], sbuf);
|
|
return mysql_query(mp, buf);
|
|
}
|
|
|
|
int db_insert_id() {
|
|
mysql_query(mp, "select LAST_INSERT_ID()");
|
|
rp = mysql_store_result(mp);
|
|
row = mysql_fetch_row(rp);
|
|
return atoi(row[0]);
|
|
}
|
|
|
|
int db_delete(int id, int type) {
|
|
char buf[MAX_QUERY_LEN];
|
|
|
|
sprintf(buf, "delete from %s where id=%d", table_name[type], id);
|
|
return mysql_query(mp, buf);
|
|
}
|
|
|
|
int db_lookup_id(int i, void* vp, int type) {
|
|
char buf[MAX_QUERY_LEN];
|
|
assert(vp!=NULL);
|
|
sprintf(buf, "select * from %s where id=%d", table_name[type], i);
|
|
mysql_query(mp, buf);
|
|
rp = mysql_store_result(mp);
|
|
if (!rp) return -1;
|
|
row = mysql_fetch_row(rp);
|
|
if (row) row_to_struct(row, vp, type);
|
|
mysql_free_result(rp);
|
|
return (row == 0);
|
|
}
|
|
|
|
int db_lookup(void* vp, int type, char* clause) {
|
|
char buf[MAX_QUERY_LEN];
|
|
assert(vp!=NULL);
|
|
assert(clause!=NULL);
|
|
sprintf(buf, "select * from %s where %s", table_name[type], clause);
|
|
mysql_query(mp, buf);
|
|
rp = mysql_store_result(mp);
|
|
if (!rp) return -1;
|
|
row = mysql_fetch_row(rp);
|
|
if (row) row_to_struct(row, vp, type);
|
|
mysql_free_result(rp);
|
|
return (row == 0);
|
|
}
|
|
|
|
int db_update(void* vp, int type) {
|
|
char buf[MAX_QUERY_LEN], sbuf[MAX_QUERY_LEN];
|
|
assert(vp!=NULL);
|
|
struct_to_str(vp, sbuf, type);
|
|
sprintf(
|
|
buf,
|
|
"update %s set %s where id=%d",
|
|
table_name[type], sbuf, *id(vp, type)
|
|
);
|
|
return mysql_query(mp, buf);
|
|
}
|
|
|
|
int db_enum(ENUM& e, void* p, int type, char* clause, int limit) {
|
|
char buf[MAX_QUERY_LEN], buf2[256];
|
|
//assert(p!=NULL);
|
|
//assert(clause!=NULL);
|
|
if (!e.active) {
|
|
e.active = 1;
|
|
sprintf(buf, "select * from %s %s", table_name[type], clause?clause:"");
|
|
if (limit) {
|
|
sprintf(buf2, " limit %d", limit);
|
|
strcat(buf, buf2);
|
|
}
|
|
mysql_query(mp, buf);
|
|
e.rp = mysql_store_result(mp);
|
|
if (!e.rp) return -1;
|
|
}
|
|
row = mysql_fetch_row(e.rp);
|
|
if (!row) {
|
|
mysql_free_result(e.rp);
|
|
e.active = 0;
|
|
return 1;
|
|
} else {
|
|
row_to_struct(row, p, type);
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
int db_enum_field(ENUM& e, int type, char* field, char* clause) {
|
|
char buf[MAX_QUERY_LEN];
|
|
assert(field!=NULL);
|
|
assert(clause!=NULL);
|
|
if (!e.active) {
|
|
e.active = 1;
|
|
sprintf(buf, "select %s from %s %s", field, table_name[type], clause);
|
|
mysql_query(mp, buf);
|
|
e.rp = mysql_store_result(mp);
|
|
if (!e.rp) return -1;
|
|
}
|
|
row = mysql_fetch_row(e.rp);
|
|
if (!row) {
|
|
mysql_free_result(e.rp);
|
|
e.active = 0;
|
|
return 1;
|
|
} else {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
int db_query_int(int* ip, char* query) {
|
|
assert(ip!=NULL);
|
|
assert(query!=NULL);
|
|
mysql_query(mp, query);
|
|
rp = mysql_store_result(mp);
|
|
if (!rp) return -1;
|
|
row = mysql_fetch_row(rp);
|
|
if (!row) return -1;
|
|
*ip = atoi(row[0]);
|
|
mysql_free_result(rp);
|
|
return 0;
|
|
}
|
|
|
|
int db_count(int* np, char* what, int type, char* clause) {
|
|
char buf[MAX_QUERY_LEN];
|
|
assert(np!=NULL);
|
|
assert(what!=NULL);
|
|
assert(clause!=NULL);
|
|
sprintf(buf, "select count(%s) from %s %s", what, table_name[type], clause);
|
|
return db_query_int(np, buf);
|
|
}
|
|
|