Skip to content

Instantly share code, notes, and snippets.

@ice799
Created August 27, 2008 23:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ice799/7612 to your computer and use it in GitHub Desktop.
Save ice799/7612 to your computer and use it in GitHub Desktop.
diff --git a/ext/mysql.c b/ext/mysql.c
index 765cfde..1e12557 100644
--- a/ext/mysql.c
+++ b/ext/mysql.c
@@ -1064,14 +1064,37 @@ static VALUE fetch_row(VALUE obj)
return ary;
}
-/* fetch_hash2 (internal) */
-static VALUE fetch_hash2(VALUE obj, VALUE with_table)
+/* fetch field names */
+static VALUE fetch_field_names(VALUE obj, VALUE with_table)
{
MYSQL_RES* res = GetMysqlRes(obj);
unsigned int n = mysql_num_fields(res);
+ MYSQL_FIELD* fields = mysql_fetch_fields(res);
+ unsigned int i;
+ VALUE ary;
+ ary = rb_ary_new2(n);
+ for (i=0; i<n; i++) {
+ VALUE col;
+ if (with_table == Qnil || with_table == Qfalse)
+ col = rb_tainted_str_new2(fields[i].name);
+ else {
+ col = rb_tainted_str_new(fields[i].table, strlen(fields[i].table)+strlen(fields[i].name)+1);
+ RSTRING(col)->ptr[strlen(fields[i].table)] = '.';
+ strcpy(RSTRING(col)->ptr+strlen(fields[i].table)+1, fields[i].name);
+ }
+ rb_ary_store(ary, i, col);
+ }
+ return ary;
+}
+
+
+/* fetch_hash2 (internal) */
+static VALUE fetch_hash2(VALUE obj, VALUE field_names)
+{
+ MYSQL_RES* res = GetMysqlRes(obj);
MYSQL_ROW row = mysql_fetch_row(res);
+ unsigned int n = mysql_num_fields(res);
unsigned long* lengths = mysql_fetch_lengths(res);
- MYSQL_FIELD* fields = mysql_fetch_fields(res);
unsigned int i;
VALUE hash;
VALUE colname;
@@ -1079,36 +1102,11 @@ static VALUE fetch_hash2(VALUE obj, VALUE with_table)
return Qnil;
hash = rb_hash_new();
- if (with_table == Qnil || with_table == Qfalse) {
- colname = rb_iv_get(obj, "colname");
- if (colname == Qnil) {
- colname = rb_ary_new2(n);
- for (i=0; i<n; i++) {
- VALUE s = rb_tainted_str_new2(fields[i].name);
- rb_obj_freeze(s);
- rb_ary_store(colname, i, s);
- }
- rb_obj_freeze(colname);
- rb_iv_set(obj, "colname", colname);
- }
- } else {
- colname = rb_iv_get(obj, "tblcolname");
- if (colname == Qnil) {
- colname = rb_ary_new2(n);
- for (i=0; i<n; i++) {
- int len = strlen(fields[i].table)+strlen(fields[i].name)+1;
- VALUE s = rb_tainted_str_new(NULL, len);
- snprintf(RSTRING_PTR(s), len+1, "%s.%s", fields[i].table, fields[i].name);
- rb_obj_freeze(s);
- rb_ary_store(colname, i, s);
- }
- rb_obj_freeze(colname);
- rb_iv_set(obj, "tblcolname", colname);
- }
- }
for (i=0; i<n; i++) {
- rb_hash_aset(hash, rb_ary_entry(colname, i), row[i]? rb_tainted_str_new(row[i], lengths[i]): Qnil);
+ VALUE col = rb_ary_entry(field_names, i);
+ rb_hash_aset(hash, col, row[i]? rb_tainted_str_new(row[i], lengths[i]): Qnil);
}
+
return hash;
}
@@ -1120,7 +1118,7 @@ static VALUE fetch_hash(int argc, VALUE* argv, VALUE obj)
rb_scan_args(argc, argv, "01", &with_table);
if (with_table == Qnil)
with_table = Qfalse;
- return fetch_hash2(obj, with_table);
+ return fetch_hash2(obj, fetch_field_names(obj, with_table));
}
/* field_seek(offset) */
@@ -1197,15 +1195,38 @@ static VALUE each_hash(int argc, VALUE* argv, VALUE obj)
{
VALUE with_table;
VALUE hash;
+ VALUE field_names;
+
check_free(obj);
rb_scan_args(argc, argv, "01", &with_table);
if (with_table == Qnil)
with_table = Qfalse;
- while ((hash = fetch_hash2(obj, with_table)) != Qnil)
+ field_names = fetch_field_names(obj, with_table);
+ while ((hash = fetch_hash2(obj, field_names)) != Qnil)
rb_yield(hash);
return obj;
}
+/* all_hashes(with_table=false) */
+static VALUE all_hashes(int argc, VALUE* argv, VALUE obj)
+{
+ VALUE with_table;
+ VALUE field_names;
+ VALUE res;
+ unsigned int n,i;
+ check_free(obj);
+ rb_scan_args(argc, argv, "01", &with_table);
+ if (with_table == Qnil)
+ with_table = Qfalse;
+ field_names = fetch_field_names(obj, with_table);
+ n = mysql_num_rows(GetMysqlRes(obj));
+ res = rb_ary_new2(n);
+ for (i=0; i<n; i++) {
+ rb_ary_store(res, i, fetch_hash2(obj, field_names));
+ }
+ return res;
+}
+
/*-------------------------------
* Mysql::Field object method
*/
@@ -2155,6 +2176,7 @@ void Init_mysql(void)
rb_define_method(cMysqlRes, "row_tell", row_tell, 0);
rb_define_method(cMysqlRes, "each", each, 0);
rb_define_method(cMysqlRes, "each_hash", each_hash, -1);
+ rb_define_method(cMysqlRes, "all_hashes", all_hashes, -1);
/* MysqlField object method */
rb_define_method(cMysqlField, "name", field_name, 0);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment