slim-attributes 0.2 → 0.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -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