/* This file is part of guile-sql. Copyright (C) 2002,2004 Sergey Poznyakoff This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifdef HAVE_CONFIG_H # include #endif #include #include #include SCM s_mysql_mark(struct sql_connect *conn) { return SCM_BOOL_F; } scm_sizet s_mysql_free(struct sql_connect *conn) { MYSQL *mysql = (MYSQL*) conn->data; if (!mysql) return 0; mysql_close(mysql); free(mysql); return sizeof(MYSQL); } SCM s_mysql_connect (char *hostname, int port, char *dbname, char *user, char *pass, char *why) { MYSQL *mysql; SCM smob; struct sql_connect *conn; char *socket_path = NULL; mysql = mysql_init(NULL); if (!mysql) return SCM_BOOL_F; if (hostname[0] == '/') { socket_path = hostname; hostname = "localhost"; } if (!mysql_real_connect(mysql, hostname, user, pass, dbname, port, socket_path, 0)) { mysql_close(mysql); return SCM_BOOL_F; } smob = sql_connect_create("mysql"); conn = (struct sql_connect *)SCM_CDR(smob); conn->data = mysql; return smob; } SCM s_mysql_query(struct sql_connect *conn, char *query) { MYSQL *mysql = conn->data; MYSQL_RES *result; SCM cell; if (mysql_query(mysql, query)) scm_misc_error("s_mysql_query", "MySQL error: ~S", SCM_LIST1(scm_makfrom0str(mysql_error(mysql)))); result = mysql_store_result(mysql); if (result) { int nfields = mysql_num_fields(result); int nrows = mysql_num_rows(result); int i, j; SCM row_head = SCM_EOL, row_tail; for (i = 0; i < nrows; i++) { SCM new_row; SCM head = SCM_EOL, tail; MYSQL_ROW row = mysql_fetch_row(result); if (!row) break; for (j = 0; j < nfields; j++) { SCM new_elt; SCM_NEWCELL(new_elt); SCM_SETCAR(new_elt, scm_makfrom0str(row[j])); if (head == SCM_EOL) head = new_elt; else SCM_SETCDR(tail, new_elt); tail = new_elt; } if (head != SCM_EOL) SCM_SETCDR(tail, SCM_EOL); SCM_NEWCELL(new_row); SCM_SETCAR(new_row, head); if (row_head == SCM_EOL) row_head = new_row; else SCM_SETCDR(row_tail, new_row); row_tail = new_row; } if (row_head != SCM_EOL) SCM_SETCDR(row_tail, SCM_EOL); cell = row_head; mysql_free_result(result); } else { /* should it have returned something? */ if (mysql_field_count(mysql) == 0) { cell = scm_makenum(mysql_affected_rows(mysql)); } else { /* mysql_store_result() should have returned data */ scm_misc_error("s_mysql_query", "MySQL error: ~S", SCM_LIST1(scm_makfrom0str(mysql_error(mysql)))); } } return cell; } void s_mysql_close(struct sql_connect *conn) { if (conn->data) mysql_close(conn->data); conn->data = NULL; } struct sql_iface mysql_iface = { "mysql", s_mysql_mark, s_mysql_free, s_mysql_connect, s_mysql_close, s_mysql_query, };