Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

[MySql] Condense .query and .query_no_results into a single method th…

…at returns a table for a select, and returns an integer count for insert, update and delete for number of rows affected. Several other code cleanups.
  • Loading branch information...
commit f6489a7ee46824f8e3b81e5bc2d2fb686adbb1ac 1 parent 77caf91
@Whiteknight authored
View
11 mysql/pmc/mysqldatarow.pmc
@@ -5,6 +5,7 @@ INTVAL MySqlDataRow_type;
pmclass MySqlDataRow dynpmc auto_attrs provides array provides hash {
ATTR PMC *table;
ATTR PMC *data;
+ ATTR INTVAL row_index;
void class_init() {
MySqlDataRow_type = entry;
@@ -25,6 +26,16 @@ pmclass MySqlDataRow dynpmc auto_attrs provides array provides hash {
Parrot_gc_mark_PMC_alive(INTERP, attr->data);
}
+ VTABLE void set_integer_native(INTVAL idx)
+ {
+ PARROT_MYSQLDATAROW(SELF)->row_index = idx;
+ }
+
+ VTABLE INTVAL get_integer()
+ {
+ return PARROT_MYSQLDATAROW(SELF)->row_index;
+ }
+
VTABLE void set_pmc(PMC *data)
{
PARROT_MYSQLDATAROW(SELF)->data = data;
View
24 mysql/pmc/mysqldatatable.pmc
@@ -1,6 +1,12 @@
#include "ps_mysql.h"
#define GET_RESULT(s) ((MYSQL_RES*)PARROT_MYSQLDATATABLE(s)->result)
#define GET_COLNAMES(s) (PARROT_MYSQLDATATABLE(s)->colnames)
+#define FETCH_NEXT_ROW(a) do { \
+ MYSQL_RES * const __result = (MYSQL_RES*)(a)->result; \
+ (a)->current_row = mysql_fetch_row(__result); \
+ (a)->current_row_lengths = mysql_fetch_lengths(__result); \
+ (a)->current_row_idx = (a)->current_row_idx + 1; \
+} while(0)
INTVAL MySqlDataTable_type;
@@ -10,6 +16,7 @@ pmclass MySqlDataTable dynpmc auto_attrs provides iterator {
ATTR void *current_row;
ATTR void *current_row_lengths;
ATTR INTVAL num_fields;
+ ATTR INTVAL current_row_idx;
void class_init() {
MySqlDataTable_type = entry;
@@ -22,6 +29,7 @@ pmclass MySqlDataTable dynpmc auto_attrs provides iterator {
VTABLE void set_pointer(void *rawptr)
{
+ Parrot_MySqlDataTable_attributes * const attrs = PARROT_MYSQLDATATABLE(SELF);
MYSQL_RES * const result = (MYSQL_RES*)rawptr;
INTVAL num_fields = mysql_num_fields(result);
Hash * const colnames = Parrot_hash_create_sized(INTERP, enum_hash_int, Hash_key_type_STRING, num_fields);
@@ -34,11 +42,11 @@ pmclass MySqlDataTable dynpmc auto_attrs provides iterator {
idx++;
}
- PARROT_MYSQLDATATABLE(SELF)->colnames = colnames;
- PARROT_MYSQLDATATABLE(SELF)->result = rawptr;
- PARROT_MYSQLDATATABLE(SELF)->current_row = mysql_fetch_row(result);
- PARROT_MYSQLDATATABLE(SELF)->current_row_lengths = mysql_fetch_lengths(result);
- PARROT_MYSQLDATATABLE(SELF)->num_fields = num_fields;
+ attrs->colnames = colnames;
+ attrs->result = rawptr;
+ attrs->num_fields = num_fields;
+ attrs->current_row_idx = -1;
+ FETCH_NEXT_ROW(attrs);
}
VTABLE void mark()
@@ -71,13 +79,17 @@ pmclass MySqlDataTable dynpmc auto_attrs provides iterator {
INTVAL num_fields = PARROT_MYSQLDATATABLE(SELF)->num_fields;
PMC * const rowpmc = Parrot_pmc_new_init(INTERP, MySqlDataRow_type, SELF);
PMC * const data = Parrot_pmc_new_init_int(INTERP, enum_class_FixedStringArray, num_fields);
+ const INTVAL row_idx = attrs->current_row_idx;
INTVAL i = 0;
for (; i < num_fields; i++) {
STRING * const field_val = Parrot_str_new_init(INTERP, row[i], (INTVAL)field_lengths[i], Parrot_binary_encoding_ptr, 0);
VTABLE_set_string_keyed_int(INTERP, data, i, field_val);
}
VTABLE_set_pmc(INTERP, rowpmc, data);
- attrs->current_row = mysql_fetch_row((MYSQL_RES*)attrs->result);
+ VTABLE_set_integer_native(INTERP, rowpmc, row_idx);
+
+ // Now update with new values for next time
+ FETCH_NEXT_ROW(attrs);
return rowpmc;
}
}
View
44 mysql/pmc/mysqldbcontext.pmc
@@ -1,5 +1,7 @@
#include "ps_mysql.h"
+
#define GET_CONN(s) ((MYSQL*)PARROT_MYSQLDBCONTEXT(s)->conn)
+#define MYSQL_EXCEPTION(i, c) Parrot_ex_throw_from_c_args((i), NULL, 0, "MySql Error %u: %s\n", mysql_errno(c), mysql_error(c))
pmclass MySQLDbContext dynpmc auto_attrs {
ATTR void *conn;
@@ -31,19 +33,7 @@ pmclass MySQLDbContext dynpmc auto_attrs {
Parrot_free_cstring(cdb);
if (!stat)
- Parrot_ex_throw_from_c_args(INTERP, NULL, 0, "MySql Error %u: %s\n", mysql_errno(conn), mysql_error(conn));
- }
-
- METHOD query_no_result(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)
- Parrot_ex_throw_from_c_args(INTERP, NULL, 0, "MySql Error %u: %s\n", mysql_errno(conn), mysql_error(conn));
+ MYSQL_EXCEPTION(INTERP, conn);
}
METHOD query(STRING * query) {
@@ -55,12 +45,30 @@ pmclass MySQLDbContext dynpmc auto_attrs {
);
if (stat)
- Parrot_ex_throw_from_c_args(INTERP, NULL, 0, "MySql Error %u: %s\n", mysql_errno(conn), mysql_error(conn));
+ MYSQL_EXCEPTION(INTERP, conn);
else {
- MYSQL_RES * const result = mysql_use_result(conn);
- PMC * const table = Parrot_pmc_new(INTERP, MySqlDataTable_type);
- VTABLE_set_pointer(INTERP, table, result);
- RETURN(PMC * table);
+ // TODO: Refactor all this
+ MYSQL_RES * const result = mysql_store_result(conn);
+ if (result) {
+ // It's a query with results, like a SELECT. Return a data table
+ // with the results
+ PMC * const table = Parrot_pmc_new(INTERP, MySqlDataTable_type);
+ VTABLE_set_pointer(INTERP, table, result);
+ // TODO: Multiple result sets
+ 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);
+ }
+ }
}
}
}
+
Please sign in to comment.
Something went wrong with that request. Please try again.