Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Tree: 0e8b302ee1
Fetching contributors…

Cannot retrieve contributors at this time

104 lines (92 sloc) 4.171 kB
#include "ps_mysql.h"
#define GET_CONN(s) ((MYSQL*)PARROT_MYSQLDBCONTEXT(s)->conn)
#define MYSQL_EXCEPTION(i, c, x) Parrot_ex_throw_from_c_args((i), NULL, 0, "MySql Error %u at %s: %s\n", mysql_errno(c), (x), mysql_error(c))
pmclass MySQLDbContext dynpmc auto_attrs {
ATTR void *conn;
VTABLE void init() {
MYSQL * const conn = mysql_init(NULL);
PARROT_MYSQLDBCONTEXT(SELF)->conn = (void*)conn;
PObj_custom_destroy_SET(SELF);
}
VTABLE void destroy() {
MYSQL * const conn = GET_CONN(SELF);
if (conn)
mysql_close(conn);
}
METHOD connect(STRING *server, STRING *username, STRING *password, STRING *db,
INTVAL port :optional, INTVAL have_port :opt_flag,
INTVAL client_flag :optional, INTVAL have_flags :opt_flag)
{
MYSQL * const conn = GET_CONN(SELF);
char * const cserver = Parrot_str_to_cstring(INTERP, server);
char * const cusername = Parrot_str_to_cstring(INTERP, username);
char * const cpassword = Parrot_str_to_cstring(INTERP, password);
char * const cdb = db == STRINGNULL ? NULL : Parrot_str_to_cstring(INTERP, db);
if (!have_flags)
client_flag = CLIENT_MULTI_STATEMENTS;
if (!have_port)
port = 0;
INTVAL stat = mysql_real_connect(conn, cserver, cusername, cpassword, cdb, port, NULL, client_flag);
Parrot_free_cstring(cserver);
Parrot_free_cstring(cusername);
Parrot_free_cstring(cpassword);
if (cdb)
Parrot_free_cstring(cdb);
if (!stat)
MYSQL_EXCEPTION(INTERP, conn, "connect");
}
METHOD query(STRING * query) {
MYSQL * const conn = GET_CONN(SELF);
INTVAL len = Parrot_str_byte_length(INTERP, query);
INTVAL stat;
STRING_TO_CSTRING(INTERP, query, cquery,
stat = mysql_real_query(conn, cquery, len);
);
if (stat)
MYSQL_EXCEPTION(INTERP, conn, "query");
else {
// TODO: Refactor all this
MYSQL_RES * result = mysql_store_result(conn);
if (result) {
// It's a query with results, like a SELECT. Return a data table
// with the results
PMC * table = Parrot_pmc_new(INTERP, MySqlDataTable_type);
VTABLE_set_pointer(INTERP, table, result);
mysql_free_result(result);
if (mysql_more_results(conn)) {
PMC * const set = Parrot_pmc_new(INTERP, enum_class_ResizablePMCArray);
VTABLE_push_pmc(INTERP, set, table);
// TODO: Can we capture errors from this?
while(mysql_next_result(conn) == 0) {
result = mysql_store_result(conn);
if (result) {
table = Parrot_pmc_new(INTERP, MySqlDataTable_type);
VTABLE_set_pointer(INTERP, table, result);
mysql_free_result(result);
VTABLE_push_pmc(INTERP, set, table);
} else {
if (mysql_field_count(conn) == 0) {
// TODO: What here?
} else {
MYSQL_EXCEPTION(INTERP, conn, "read result set");
}
}
}
RETURN(PMC *set);
}
RETURN(PMC *table);
} else {
if (mysql_field_count(conn) == 0) {
// It was a query with no results, like INSERT, UPDATE or DELETE.
// Return the number of affected rows
const INTVAL num_rows = mysql_affected_rows(conn);
RETURN(INTVAL num_rows);
} else {
// The query should have returned data, but did not due to
// an error. Alert the user.
MYSQL_EXCEPTION(INTERP, conn, "read result table");
}
}
}
}
}
Jump to Line
Something went wrong with that request. Please try again.