slim-attributes 0.2 → 0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,11 +1,11 @@
1
1
  #include "ruby.h"
2
+ #include "st.h"
2
3
 
3
4
  #include <mysql.h>
4
5
  #include <errmsg.h>
5
6
  #include <mysqld_error.h>
6
7
 
7
8
  #define GetMysqlRes(obj) (Check_Type(obj, T_DATA), ((struct mysql_res*)DATA_PTR(obj))->res)
8
- #define GetLongPtr(obj) (Check_Type(obj, T_DATA), (long*)DATA_PTR(obj))
9
9
  #define GetCharPtr(obj) (Check_Type(obj, T_DATA), (char*)DATA_PTR(obj))
10
10
  #define GetCharStarPtr(obj) (Check_Type(obj, T_DATA), (char**)DATA_PTR(obj))
11
11
 
@@ -18,8 +18,10 @@ struct mysql_res {
18
18
  };
19
19
 
20
20
  // row info
21
- #define SLIM_IS_NULL (char)1
22
- #define SLIM_IS_SET (char)2
21
+ #define SLIM_IS_NULL (char)0x01
22
+ #define SLIM_IS_SET (char)0x02
23
+
24
+ #define GET_COL_IV_NAME(str, col_number) sprintf(str, "@col_%d", col_number)
23
25
 
24
26
  static VALUE all_hashes(VALUE obj) {
25
27
  MYSQL_RES *res = GetMysqlRes(obj);
@@ -34,7 +36,7 @@ static VALUE all_hashes(VALUE obj) {
34
36
 
35
37
  /* hash of column names */
36
38
  col_names_hsh = rb_hash_new();
37
- for (i=0; i<nf; i++) {
39
+ for (i=0; i < nf; i++) {
38
40
  rb_hash_aset(col_names_hsh, rb_str_new2(fields[i].name), INT2FIX(i));
39
41
  }
40
42
 
@@ -57,28 +59,27 @@ static VALUE all_hashes(VALUE obj) {
57
59
  rb_iv_set(frh, "@pointers", Data_Wrap_Struct(cClass, 0, free, pointers_space));
58
60
  rb_iv_set(frh, "@row_info", Data_Wrap_Struct(cClass, 0, free, row_info_space));
59
61
  rb_iv_set(frh, "@field_indexes", col_names_hsh);
60
- rb_iv_set(frh, "@row", rb_ary_new()); // ready to hold fetched fields
61
62
  rb_ary_store(all_hashes_ary, i, frh);
62
63
  }
63
64
  return all_hashes_ary;
64
65
  }
65
66
 
66
67
  static VALUE fetch_by_index(VALUE obj, VALUE index) {
67
- VALUE row_ary, contents;
68
- char *row_info, **pointers, *start;
68
+ VALUE contents;
69
+ char *row_info, **pointers, *start, col_name[16];
69
70
  long col_number = FIX2LONG(index);
70
71
  unsigned int length;
71
72
 
72
73
  row_info = GetCharPtr(rb_iv_get(obj, "@row_info")) + col_number;
73
74
  if (*row_info == SLIM_IS_NULL) return Qnil; // return nil if null from db
74
- row_ary = rb_iv_get(obj, "@row");
75
- if (*row_info == SLIM_IS_SET) return rb_ary_entry(row_ary, col_number); // was set already, return array entry
75
+ GET_COL_IV_NAME(col_name, col_number);
76
+ if (*row_info == SLIM_IS_SET) return rb_iv_get(obj, col_name); // was set already, return array entry
76
77
 
77
78
  pointers = GetCharStarPtr(rb_iv_get(obj, "@pointers"));
78
79
  start = pointers[col_number];
79
80
  length = pointers[col_number + 1] - start;
80
81
  contents = rb_tainted_str_new(start, length);
81
- rb_ary_store(row_ary, col_number, contents);
82
+ rb_iv_set(obj, col_name, contents);
82
83
  *row_info = SLIM_IS_SET;
83
84
  return contents;
84
85
  }
@@ -95,6 +96,7 @@ static VALUE slim_fetch(VALUE obj, VALUE name) {
95
96
  static VALUE set_element(VALUE obj, VALUE name, VALUE val) {
96
97
  VALUE real_hash, hash_lookup;
97
98
  long col_number;
99
+ char col_name[16];
98
100
 
99
101
  real_hash = rb_iv_get(obj, "@real_hash");
100
102
  if (!NIL_P(real_hash)) return rb_hash_aset(real_hash, name, val);
@@ -102,11 +104,32 @@ static VALUE set_element(VALUE obj, VALUE name, VALUE val) {
102
104
  hash_lookup = rb_hash_aref(rb_iv_get(obj, "@field_indexes"), name);
103
105
  if (NIL_P(hash_lookup)) return rb_funcall(rb_funcall(obj, rb_intern("to_hash"), 0), rb_intern("[]="), 2, name, val);
104
106
  col_number = FIX2LONG(hash_lookup);
105
- rb_ary_store(rb_iv_get(obj, "@row"), col_number, val);
107
+ GET_COL_IV_NAME(col_name, col_number);
108
+ rb_iv_set(obj, col_name, val);
106
109
  GetCharPtr(rb_iv_get(obj, "@row_info"))[col_number] = SLIM_IS_SET;
107
110
  return val;
108
111
  }
109
112
 
113
+ static VALUE dup(VALUE obj) {
114
+ VALUE real_hash, frh, field_indexes;
115
+ int nf, i;
116
+ char *row_info_space, col_name[16];
117
+
118
+ real_hash = rb_iv_get(obj, "@real_hash");
119
+ if (!NIL_P(real_hash)) return rb_obj_dup(real_hash);
120
+
121
+ field_indexes = rb_iv_get(obj, "@field_indexes");
122
+ nf = RHASH(field_indexes)->tbl->num_entries;
123
+ row_info_space = malloc(nf);
124
+ memcpy(row_info_space, GetCharPtr(rb_iv_get(obj, "@row_info")), nf);
125
+ for (i=0; i < nf; i++) row_info_space[i] &= ~SLIM_IS_SET; // remove any set flags
126
+ frh = rb_class_new_instance(0, NULL, cRowHash);
127
+ rb_iv_set(frh, "@pointers", rb_iv_get(obj, "@pointers"));
128
+ rb_iv_set(frh, "@row_info", Data_Wrap_Struct(cClass, 0, free, row_info_space));
129
+ rb_iv_set(frh, "@field_indexes", field_indexes);
130
+ return frh;
131
+ }
132
+
110
133
  void Init_slim_attrib_ext() {
111
134
  VALUE c = rb_cObject;
112
135
  c = rb_const_get_at(c, rb_intern("Mysql"));
@@ -117,4 +140,5 @@ void Init_slim_attrib_ext() {
117
140
  rb_define_private_method(cRowHash, "fetch_by_index", (VALUE(*)(ANYARGS))fetch_by_index, 1);
118
141
  rb_define_method(cRowHash, "[]", (VALUE(*)(ANYARGS))slim_fetch, 1);
119
142
  rb_define_method(cRowHash, "[]=", (VALUE(*)(ANYARGS))set_element, 2);
143
+ rb_define_method(cRowHash, "dup", (VALUE(*)(ANYARGS))dup, 0);
120
144
  }
@@ -21,16 +21,13 @@ class Mysql::Result
21
21
  end
22
22
 
23
23
  def to_hash
24
- @real_hash ||= begin
25
- @field_indexes.each_value {|v| fetch_by_index(v)}
26
- @field_indexes.inject({}) {|memo, fi| memo[fi[0]] = @row[fi[1]]; memo}
27
- end
24
+ @real_hash ||= @field_indexes.inject({}) {|memo, fi| memo[fi[0]] = fetch_by_index(fi[1]); memo}
28
25
  end
29
26
 
30
27
  def to_a
31
28
  to_hash.to_a
32
29
  end
33
-
30
+
34
31
  def method_missing(name, *args, &block)
35
32
  to_hash.send(name, *args, &block)
36
33
  end
metadata CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.9.4
3
3
  specification_version: 1
4
4
  name: slim-attributes
5
5
  version: !ruby/object:Gem::Version
6
- version: "0.2"
7
- date: 2008-04-09 00:00:00 +03:00
6
+ version: "0.3"
7
+ date: 2008-04-21 00:00:00 +03:00
8
8
  summary: Slim attributes boosts speed in Rails/Mysql ActiveRecord Models by avoiding instantiating Hashes for each result row, and lazily instantiating attributes as needed
9
9
  require_paths:
10
10
  - lib